Fix vpp built-in version of api_unformat_sw_if_index(...)
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 #if VPP_API_TEST_BUILTIN == 0
116 static uword
117 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
118 {
119   vat_main_t *vam = va_arg (*args, vat_main_t *);
120   u32 *result = va_arg (*args, u32 *);
121   u8 *if_name;
122   uword *p;
123
124   if (!unformat (input, "%s", &if_name))
125     return 0;
126
127   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
128   if (p == 0)
129     return 0;
130   *result = p[0];
131   return 1;
132 }
133
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #else /* VPP_API_TEST_BUILTIN == 1 */
391 static uword
392 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
393 {
394   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
395   vnet_main_t *vnm = vnet_get_main ();
396   u32 *result = va_arg (*args, u32 *);
397   u32 sw_if_index;
398
399   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
400     return 0;
401
402   *result = sw_if_index;
403   return 1;
404 }
405 #endif /* VPP_API_TEST_BUILTIN */
406
407 static uword
408 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "kbps"))
413     *r = SSE2_QOS_RATE_KBPS;
414   else if (unformat (input, "pps"))
415     *r = SSE2_QOS_RATE_PPS;
416   else
417     return 0;
418   return 1;
419 }
420
421 static uword
422 unformat_policer_round_type (unformat_input_t * input, va_list * args)
423 {
424   u8 *r = va_arg (*args, u8 *);
425
426   if (unformat (input, "closest"))
427     *r = SSE2_QOS_ROUND_TO_CLOSEST;
428   else if (unformat (input, "up"))
429     *r = SSE2_QOS_ROUND_TO_UP;
430   else if (unformat (input, "down"))
431     *r = SSE2_QOS_ROUND_TO_DOWN;
432   else
433     return 0;
434   return 1;
435 }
436
437 static uword
438 unformat_policer_type (unformat_input_t * input, va_list * args)
439 {
440   u8 *r = va_arg (*args, u8 *);
441
442   if (unformat (input, "1r2c"))
443     *r = SSE2_QOS_POLICER_TYPE_1R2C;
444   else if (unformat (input, "1r3c"))
445     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
446   else if (unformat (input, "2r3c-2698"))
447     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
448   else if (unformat (input, "2r3c-4115"))
449     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
450   else if (unformat (input, "2r3c-mef5cf1"))
451     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
452   else
453     return 0;
454   return 1;
455 }
456
457 static uword
458 unformat_dscp (unformat_input_t * input, va_list * va)
459 {
460   u8 *r = va_arg (*va, u8 *);
461
462   if (0);
463 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
464   foreach_vnet_dscp
465 #undef _
466     else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_action_type (unformat_input_t * input, va_list * va)
473 {
474   sse2_qos_pol_action_params_st *a
475     = va_arg (*va, sse2_qos_pol_action_params_st *);
476
477   if (unformat (input, "drop"))
478     a->action_type = SSE2_QOS_ACTION_DROP;
479   else if (unformat (input, "transmit"))
480     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
481   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
482     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
490 {
491   u32 *r = va_arg (*va, u32 *);
492   u32 tid;
493
494   if (unformat (input, "ip4"))
495     tid = POLICER_CLASSIFY_TABLE_IP4;
496   else if (unformat (input, "ip6"))
497     tid = POLICER_CLASSIFY_TABLE_IP6;
498   else if (unformat (input, "l2"))
499     tid = POLICER_CLASSIFY_TABLE_L2;
500   else
501     return 0;
502
503   *r = tid;
504   return 1;
505 }
506
507 static uword
508 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
509 {
510   u32 *r = va_arg (*va, u32 *);
511   u32 tid;
512
513   if (unformat (input, "ip4"))
514     tid = FLOW_CLASSIFY_TABLE_IP4;
515   else if (unformat (input, "ip6"))
516     tid = FLOW_CLASSIFY_TABLE_IP6;
517   else
518     return 0;
519
520   *r = tid;
521   return 1;
522 }
523
524 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
525 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
526 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
527 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
528
529 #if (VPP_API_TEST_BUILTIN==0)
530 uword
531 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
532 {
533   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
534   mfib_itf_attribute_t attr;
535
536   old = *iflags;
537   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
538   {
539     if (unformat (input, mfib_itf_flag_long_names[attr]))
540       *iflags |= (1 << attr);
541   }
542   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_itf_flag_names[attr]))
545       *iflags |= (1 << attr);
546   }
547
548   return (old == *iflags ? 0 : 1);
549 }
550
551 uword
552 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
553 {
554   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
555   mfib_entry_attribute_t attr;
556
557   old = *eflags;
558   FOR_EACH_MFIB_ATTRIBUTE (attr)
559   {
560     if (unformat (input, mfib_flag_long_names[attr]))
561       *eflags |= (1 << attr);
562   }
563   FOR_EACH_MFIB_ATTRIBUTE (attr)
564   {
565     if (unformat (input, mfib_flag_names[attr]))
566       *eflags |= (1 << attr);
567   }
568
569   return (old == *eflags ? 0 : 1);
570 }
571
572 u8 *
573 format_ip4_address (u8 * s, va_list * args)
574 {
575   u8 *a = va_arg (*args, u8 *);
576   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
577 }
578
579 u8 *
580 format_ip6_address (u8 * s, va_list * args)
581 {
582   ip6_address_t *a = va_arg (*args, ip6_address_t *);
583   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
584
585   i_max_n_zero = ARRAY_LEN (a->as_u16);
586   max_n_zeros = 0;
587   i_first_zero = i_max_n_zero;
588   n_zeros = 0;
589   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
590     {
591       u32 is_zero = a->as_u16[i] == 0;
592       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
593         {
594           i_first_zero = i;
595           n_zeros = 0;
596         }
597       n_zeros += is_zero;
598       if ((!is_zero && n_zeros > max_n_zeros)
599           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
600         {
601           i_max_n_zero = i_first_zero;
602           max_n_zeros = n_zeros;
603           i_first_zero = ARRAY_LEN (a->as_u16);
604           n_zeros = 0;
605         }
606     }
607
608   last_double_colon = 0;
609   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
610     {
611       if (i == i_max_n_zero && max_n_zeros > 1)
612         {
613           s = format (s, "::");
614           i += max_n_zeros - 1;
615           last_double_colon = 1;
616         }
617       else
618         {
619           s = format (s, "%s%x",
620                       (last_double_colon || i == 0) ? "" : ":",
621                       clib_net_to_host_u16 (a->as_u16[i]));
622           last_double_colon = 0;
623         }
624     }
625
626   return s;
627 }
628
629 /* Format an IP46 address. */
630 u8 *
631 format_ip46_address (u8 * s, va_list * args)
632 {
633   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
634   ip46_type_t type = va_arg (*args, ip46_type_t);
635   int is_ip4 = 1;
636
637   switch (type)
638     {
639     case IP46_TYPE_ANY:
640       is_ip4 = ip46_address_is_ip4 (ip46);
641       break;
642     case IP46_TYPE_IP4:
643       is_ip4 = 1;
644       break;
645     case IP46_TYPE_IP6:
646       is_ip4 = 0;
647       break;
648     }
649
650   return is_ip4 ?
651     format (s, "%U", format_ip4_address, &ip46->ip4) :
652     format (s, "%U", format_ip6_address, &ip46->ip6);
653 }
654
655 u8 *
656 format_ethernet_address (u8 * s, va_list * args)
657 {
658   u8 *a = va_arg (*args, u8 *);
659
660   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
661                  a[0], a[1], a[2], a[3], a[4], a[5]);
662 }
663 #endif
664
665 static void
666 increment_v4_address (ip4_address_t * a)
667 {
668   u32 v;
669
670   v = ntohl (a->as_u32) + 1;
671   a->as_u32 = ntohl (v);
672 }
673
674 static void
675 increment_v6_address (ip6_address_t * a)
676 {
677   u64 v0, v1;
678
679   v0 = clib_net_to_host_u64 (a->as_u64[0]);
680   v1 = clib_net_to_host_u64 (a->as_u64[1]);
681
682   v1 += 1;
683   if (v1 == 0)
684     v0 += 1;
685   a->as_u64[0] = clib_net_to_host_u64 (v0);
686   a->as_u64[1] = clib_net_to_host_u64 (v1);
687 }
688
689 static void
690 increment_mac_address (u64 * mac)
691 {
692   u64 tmp = *mac;
693
694   tmp = clib_net_to_host_u64 (tmp);
695   tmp += 1 << 16;               /* skip unused (least significant) octets */
696   tmp = clib_host_to_net_u64 (tmp);
697   *mac = tmp;
698 }
699
700 static void vl_api_create_loopback_reply_t_handler
701   (vl_api_create_loopback_reply_t * mp)
702 {
703   vat_main_t *vam = &vat_main;
704   i32 retval = ntohl (mp->retval);
705
706   vam->retval = retval;
707   vam->regenerate_interface_table = 1;
708   vam->sw_if_index = ntohl (mp->sw_if_index);
709   vam->result_ready = 1;
710 }
711
712 static void vl_api_create_loopback_reply_t_handler_json
713   (vl_api_create_loopback_reply_t * mp)
714 {
715   vat_main_t *vam = &vat_main;
716   vat_json_node_t node;
717
718   vat_json_init_object (&node);
719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
720   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
721
722   vat_json_print (vam->ofp, &node);
723   vat_json_free (&node);
724   vam->retval = ntohl (mp->retval);
725   vam->result_ready = 1;
726 }
727
728 static void vl_api_af_packet_create_reply_t_handler
729   (vl_api_af_packet_create_reply_t * mp)
730 {
731   vat_main_t *vam = &vat_main;
732   i32 retval = ntohl (mp->retval);
733
734   vam->retval = retval;
735   vam->regenerate_interface_table = 1;
736   vam->sw_if_index = ntohl (mp->sw_if_index);
737   vam->result_ready = 1;
738 }
739
740 static void vl_api_af_packet_create_reply_t_handler_json
741   (vl_api_af_packet_create_reply_t * mp)
742 {
743   vat_main_t *vam = &vat_main;
744   vat_json_node_t node;
745
746   vat_json_init_object (&node);
747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
748   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
749
750   vat_json_print (vam->ofp, &node);
751   vat_json_free (&node);
752
753   vam->retval = ntohl (mp->retval);
754   vam->result_ready = 1;
755 }
756
757 static void vl_api_create_vlan_subif_reply_t_handler
758   (vl_api_create_vlan_subif_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_vlan_subif_reply_t_handler_json
770   (vl_api_create_vlan_subif_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781
782   vam->retval = ntohl (mp->retval);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_subif_reply_t_handler
787   (vl_api_create_subif_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   i32 retval = ntohl (mp->retval);
791
792   vam->retval = retval;
793   vam->regenerate_interface_table = 1;
794   vam->sw_if_index = ntohl (mp->sw_if_index);
795   vam->result_ready = 1;
796 }
797
798 static void vl_api_create_subif_reply_t_handler_json
799   (vl_api_create_subif_reply_t * mp)
800 {
801   vat_main_t *vam = &vat_main;
802   vat_json_node_t node;
803
804   vat_json_init_object (&node);
805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
807
808   vat_json_print (vam->ofp, &node);
809   vat_json_free (&node);
810
811   vam->retval = ntohl (mp->retval);
812   vam->result_ready = 1;
813 }
814
815 static void vl_api_interface_name_renumber_reply_t_handler
816   (vl_api_interface_name_renumber_reply_t * mp)
817 {
818   vat_main_t *vam = &vat_main;
819   i32 retval = ntohl (mp->retval);
820
821   vam->retval = retval;
822   vam->regenerate_interface_table = 1;
823   vam->result_ready = 1;
824 }
825
826 static void vl_api_interface_name_renumber_reply_t_handler_json
827   (vl_api_interface_name_renumber_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   vat_json_node_t node;
831
832   vat_json_init_object (&node);
833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 /*
843  * Special-case: build the interface table, maintain
844  * the next loopback sw_if_index vbl.
845  */
846 static void vl_api_sw_interface_details_t_handler
847   (vl_api_sw_interface_details_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   u8 *s = format (0, "%s%c", mp->interface_name, 0);
851
852   hash_set_mem (vam->sw_if_index_by_interface_name, s,
853                 ntohl (mp->sw_if_index));
854
855   /* In sub interface case, fill the sub interface table entry */
856   if (mp->sw_if_index != mp->sup_sw_if_index)
857     {
858       sw_interface_subif_t *sub = NULL;
859
860       vec_add2 (vam->sw_if_subif_table, sub, 1);
861
862       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
863       strncpy ((char *) sub->interface_name, (char *) s,
864                vec_len (sub->interface_name));
865       sub->sw_if_index = ntohl (mp->sw_if_index);
866       sub->sub_id = ntohl (mp->sub_id);
867
868       sub->sub_dot1ad = mp->sub_dot1ad;
869       sub->sub_number_of_tags = mp->sub_number_of_tags;
870       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
871       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
872       sub->sub_exact_match = mp->sub_exact_match;
873       sub->sub_default = mp->sub_default;
874       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
875       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
876
877       /* vlan tag rewrite */
878       sub->vtr_op = ntohl (mp->vtr_op);
879       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
880       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
881       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
882     }
883 }
884
885 static void vl_api_sw_interface_details_t_handler_json
886   (vl_api_sw_interface_details_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t *node = NULL;
890
891   if (VAT_JSON_ARRAY != vam->json_tree.type)
892     {
893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
894       vat_json_init_array (&vam->json_tree);
895     }
896   node = vat_json_array_add (&vam->json_tree);
897
898   vat_json_init_object (node);
899   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
900   vat_json_object_add_uint (node, "sup_sw_if_index",
901                             ntohl (mp->sup_sw_if_index));
902   vat_json_object_add_uint (node, "l2_address_length",
903                             ntohl (mp->l2_address_length));
904   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
905                              sizeof (mp->l2_address));
906   vat_json_object_add_string_copy (node, "interface_name",
907                                    mp->interface_name);
908   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
909   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
910   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
911   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
912   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
913   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
914   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
915   vat_json_object_add_uint (node, "sub_number_of_tags",
916                             mp->sub_number_of_tags);
917   vat_json_object_add_uint (node, "sub_outer_vlan_id",
918                             ntohs (mp->sub_outer_vlan_id));
919   vat_json_object_add_uint (node, "sub_inner_vlan_id",
920                             ntohs (mp->sub_inner_vlan_id));
921   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
922   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
923   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
924                             mp->sub_outer_vlan_id_any);
925   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
926                             mp->sub_inner_vlan_id_any);
927   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
928   vat_json_object_add_uint (node, "vtr_push_dot1q",
929                             ntohl (mp->vtr_push_dot1q));
930   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
931   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
932   if (mp->sub_dot1ah)
933     {
934       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
935                                        format (0, "%U",
936                                                format_ethernet_address,
937                                                &mp->b_dmac));
938       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
939                                        format (0, "%U",
940                                                format_ethernet_address,
941                                                &mp->b_smac));
942       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
943       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
944     }
945 }
946
947 static void vl_api_sw_interface_set_flags_t_handler
948   (vl_api_sw_interface_set_flags_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   if (vam->interface_event_display)
952     errmsg ("interface flags: sw_if_index %d %s %s",
953             ntohl (mp->sw_if_index),
954             mp->admin_up_down ? "admin-up" : "admin-down",
955             mp->link_up_down ? "link-up" : "link-down");
956 }
957
958 static void vl_api_sw_interface_set_flags_t_handler_json
959   (vl_api_sw_interface_set_flags_t * mp)
960 {
961   /* JSON output not supported */
962 }
963
964 static void
965 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
966 {
967   vat_main_t *vam = &vat_main;
968   i32 retval = ntohl (mp->retval);
969
970   vam->retval = retval;
971   vam->shmem_result = (u8 *) mp->reply_in_shmem;
972   vam->result_ready = 1;
973 }
974
975 static void
976 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   vat_json_node_t node;
980   api_main_t *am = &api_main;
981   void *oldheap;
982   u8 *reply;
983
984   vat_json_init_object (&node);
985   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
986   vat_json_object_add_uint (&node, "reply_in_shmem",
987                             ntohl (mp->reply_in_shmem));
988   /* Toss the shared-memory original... */
989   pthread_mutex_lock (&am->vlib_rp->mutex);
990   oldheap = svm_push_data_heap (am->vlib_rp);
991
992   reply = (u8 *) (mp->reply_in_shmem);
993   vec_free (reply);
994
995   svm_pop_heap (oldheap);
996   pthread_mutex_unlock (&am->vlib_rp->mutex);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void
1006 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010
1011   vam->retval = retval;
1012   vam->cmd_reply = mp->reply;
1013   vam->result_ready = 1;
1014 }
1015
1016 static void
1017 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1018 {
1019   vat_main_t *vam = &vat_main;
1020   vat_json_node_t node;
1021
1022   vat_json_init_object (&node);
1023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1024   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1025
1026   vat_json_print (vam->ofp, &node);
1027   vat_json_free (&node);
1028
1029   vam->retval = ntohl (mp->retval);
1030   vam->result_ready = 1;
1031 }
1032
1033 static void vl_api_classify_add_del_table_reply_t_handler
1034   (vl_api_classify_add_del_table_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038   if (vam->async_mode)
1039     {
1040       vam->async_errors += (retval < 0);
1041     }
1042   else
1043     {
1044       vam->retval = retval;
1045       if (retval == 0 &&
1046           ((mp->new_table_index != 0xFFFFFFFF) ||
1047            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1048            (mp->match_n_vectors != 0xFFFFFFFF)))
1049         /*
1050          * Note: this is just barely thread-safe, depends on
1051          * the main thread spinning waiting for an answer...
1052          */
1053         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1054                 ntohl (mp->new_table_index),
1055                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1056       vam->result_ready = 1;
1057     }
1058 }
1059
1060 static void vl_api_classify_add_del_table_reply_t_handler_json
1061   (vl_api_classify_add_del_table_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   vat_json_node_t node;
1065
1066   vat_json_init_object (&node);
1067   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1068   vat_json_object_add_uint (&node, "new_table_index",
1069                             ntohl (mp->new_table_index));
1070   vat_json_object_add_uint (&node, "skip_n_vectors",
1071                             ntohl (mp->skip_n_vectors));
1072   vat_json_object_add_uint (&node, "match_n_vectors",
1073                             ntohl (mp->match_n_vectors));
1074
1075   vat_json_print (vam->ofp, &node);
1076   vat_json_free (&node);
1077
1078   vam->retval = ntohl (mp->retval);
1079   vam->result_ready = 1;
1080 }
1081
1082 static void vl_api_get_node_index_reply_t_handler
1083   (vl_api_get_node_index_reply_t * mp)
1084 {
1085   vat_main_t *vam = &vat_main;
1086   i32 retval = ntohl (mp->retval);
1087   if (vam->async_mode)
1088     {
1089       vam->async_errors += (retval < 0);
1090     }
1091   else
1092     {
1093       vam->retval = retval;
1094       if (retval == 0)
1095         errmsg ("node index %d", ntohl (mp->node_index));
1096       vam->result_ready = 1;
1097     }
1098 }
1099
1100 static void vl_api_get_node_index_reply_t_handler_json
1101   (vl_api_get_node_index_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_get_next_index_reply_t_handler
1118   (vl_api_get_next_index_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0)
1130         errmsg ("next node index %d", ntohl (mp->next_index));
1131       vam->result_ready = 1;
1132     }
1133 }
1134
1135 static void vl_api_get_next_index_reply_t_handler_json
1136   (vl_api_get_next_index_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   vat_json_node_t node;
1140
1141   vat_json_init_object (&node);
1142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1143   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1144
1145   vat_json_print (vam->ofp, &node);
1146   vat_json_free (&node);
1147
1148   vam->retval = ntohl (mp->retval);
1149   vam->result_ready = 1;
1150 }
1151
1152 static void vl_api_add_node_next_reply_t_handler
1153   (vl_api_add_node_next_reply_t * mp)
1154 {
1155   vat_main_t *vam = &vat_main;
1156   i32 retval = ntohl (mp->retval);
1157   if (vam->async_mode)
1158     {
1159       vam->async_errors += (retval < 0);
1160     }
1161   else
1162     {
1163       vam->retval = retval;
1164       if (retval == 0)
1165         errmsg ("next index %d", ntohl (mp->next_index));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_add_node_next_reply_t_handler_json
1171   (vl_api_add_node_next_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1179
1180   vat_json_print (vam->ofp, &node);
1181   vat_json_free (&node);
1182
1183   vam->retval = ntohl (mp->retval);
1184   vam->result_ready = 1;
1185 }
1186
1187 static void vl_api_show_version_reply_t_handler
1188   (vl_api_show_version_reply_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   i32 retval = ntohl (mp->retval);
1192
1193   if (retval >= 0)
1194     {
1195       errmsg ("        program: %s", mp->program);
1196       errmsg ("        version: %s", mp->version);
1197       errmsg ("     build date: %s", mp->build_date);
1198       errmsg ("build directory: %s", mp->build_directory);
1199     }
1200   vam->retval = retval;
1201   vam->result_ready = 1;
1202 }
1203
1204 static void vl_api_show_version_reply_t_handler_json
1205   (vl_api_show_version_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_string_copy (&node, "program", mp->program);
1213   vat_json_object_add_string_copy (&node, "version", mp->version);
1214   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1215   vat_json_object_add_string_copy (&node, "build_directory",
1216                                    mp->build_directory);
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void
1226 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1227 {
1228   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1229           mp->mac_ip ? "mac/ip binding" : "address resolution",
1230           format_ip4_address, &mp->address,
1231           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232 }
1233
1234 static void
1235 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1236 {
1237   /* JSON output not supported */
1238 }
1239
1240 static void
1241 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1242 {
1243   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1244           mp->mac_ip ? "mac/ip binding" : "address resolution",
1245           format_ip6_address, mp->address,
1246           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1247 }
1248
1249 static void
1250 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1251 {
1252   /* JSON output not supported */
1253 }
1254
1255 /*
1256  * Special-case: build the bridge domain table, maintain
1257  * the next bd id vbl.
1258  */
1259 static void vl_api_bridge_domain_details_t_handler
1260   (vl_api_bridge_domain_details_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1264
1265   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1266          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1267
1268   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1269          ntohl (mp->bd_id), mp->learn, mp->forward,
1270          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1271
1272   if (n_sw_ifs)
1273     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1274 }
1275
1276 static void vl_api_bridge_domain_details_t_handler_json
1277   (vl_api_bridge_domain_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t *node, *array = NULL;
1281
1282   if (VAT_JSON_ARRAY != vam->json_tree.type)
1283     {
1284       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1285       vat_json_init_array (&vam->json_tree);
1286     }
1287   node = vat_json_array_add (&vam->json_tree);
1288
1289   vat_json_init_object (node);
1290   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1291   vat_json_object_add_uint (node, "flood", mp->flood);
1292   vat_json_object_add_uint (node, "forward", mp->forward);
1293   vat_json_object_add_uint (node, "learn", mp->learn);
1294   vat_json_object_add_uint (node, "bvi_sw_if_index",
1295                             ntohl (mp->bvi_sw_if_index));
1296   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1297   array = vat_json_object_add (node, "sw_if");
1298   vat_json_init_array (array);
1299 }
1300
1301 /*
1302  * Special-case: build the bridge domain sw if table.
1303  */
1304 static void vl_api_bridge_domain_sw_if_details_t_handler
1305   (vl_api_bridge_domain_sw_if_details_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   hash_pair_t *p;
1309   u8 *sw_if_name = 0;
1310   u32 sw_if_index;
1311
1312   sw_if_index = ntohl (mp->sw_if_index);
1313   /* *INDENT-OFF* */
1314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1315   ({
1316     if ((u32) p->value[0] == sw_if_index)
1317       {
1318         sw_if_name = (u8 *)(p->key);
1319         break;
1320       }
1321   }));
1322   /* *INDENT-ON* */
1323
1324   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1325          mp->shg, sw_if_name ? (char *) sw_if_name :
1326          "sw_if_index not found!");
1327 }
1328
1329 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1330   (vl_api_bridge_domain_sw_if_details_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t *node = NULL;
1334   uword last_index = 0;
1335
1336   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1337   ASSERT (vec_len (vam->json_tree.array) >= 1);
1338   last_index = vec_len (vam->json_tree.array) - 1;
1339   node = &vam->json_tree.array[last_index];
1340   node = vat_json_object_get_element (node, "sw_if");
1341   ASSERT (NULL != node);
1342   node = vat_json_array_add (node);
1343
1344   vat_json_init_object (node);
1345   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1347   vat_json_object_add_uint (node, "shg", mp->shg);
1348 }
1349
1350 static void vl_api_control_ping_reply_t_handler
1351   (vl_api_control_ping_reply_t * mp)
1352 {
1353   vat_main_t *vam = &vat_main;
1354   i32 retval = ntohl (mp->retval);
1355   if (vam->async_mode)
1356     {
1357       vam->async_errors += (retval < 0);
1358     }
1359   else
1360     {
1361       vam->retval = retval;
1362       vam->result_ready = 1;
1363     }
1364 }
1365
1366 static void vl_api_control_ping_reply_t_handler_json
1367   (vl_api_control_ping_reply_t * mp)
1368 {
1369   vat_main_t *vam = &vat_main;
1370   i32 retval = ntohl (mp->retval);
1371
1372   if (VAT_JSON_NONE != vam->json_tree.type)
1373     {
1374       vat_json_print (vam->ofp, &vam->json_tree);
1375       vat_json_free (&vam->json_tree);
1376       vam->json_tree.type = VAT_JSON_NONE;
1377     }
1378   else
1379     {
1380       /* just print [] */
1381       vat_json_init_array (&vam->json_tree);
1382       vat_json_print (vam->ofp, &vam->json_tree);
1383       vam->json_tree.type = VAT_JSON_NONE;
1384     }
1385
1386   vam->retval = retval;
1387   vam->result_ready = 1;
1388 }
1389
1390 static void
1391 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1392 {
1393   vat_main_t *vam = &vat_main;
1394   i32 retval = ntohl (mp->retval);
1395   if (vam->async_mode)
1396     {
1397       vam->async_errors += (retval < 0);
1398     }
1399   else
1400     {
1401       vam->retval = retval;
1402       vam->result_ready = 1;
1403     }
1404 }
1405
1406 static void vl_api_l2_flags_reply_t_handler_json
1407   (vl_api_l2_flags_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1415                             ntohl (mp->resulting_feature_bitmap));
1416
1417   vat_json_print (vam->ofp, &node);
1418   vat_json_free (&node);
1419
1420   vam->retval = ntohl (mp->retval);
1421   vam->result_ready = 1;
1422 }
1423
1424 static void vl_api_bridge_flags_reply_t_handler
1425   (vl_api_bridge_flags_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->result_ready = 1;
1437     }
1438 }
1439
1440 static void vl_api_bridge_flags_reply_t_handler_json
1441   (vl_api_bridge_flags_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   vat_json_node_t node;
1445
1446   vat_json_init_object (&node);
1447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1448   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1449                             ntohl (mp->resulting_feature_bitmap));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void vl_api_tap_connect_reply_t_handler
1459   (vl_api_tap_connect_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->sw_if_index = ntohl (mp->sw_if_index);
1471       vam->result_ready = 1;
1472     }
1473
1474 }
1475
1476 static void vl_api_tap_connect_reply_t_handler_json
1477   (vl_api_tap_connect_reply_t * mp)
1478 {
1479   vat_main_t *vam = &vat_main;
1480   vat_json_node_t node;
1481
1482   vat_json_init_object (&node);
1483   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1484   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491
1492 }
1493
1494 static void
1495 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->sw_if_index = ntohl (mp->sw_if_index);
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_tap_modify_reply_t_handler_json
1512   (vl_api_tap_modify_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void
1529 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_tap_delete_reply_t_handler_json
1545   (vl_api_tap_delete_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1561   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1577   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1585                             ntohl (mp->sw_if_index));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1595   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609 }
1610
1611 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1612   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1613 {
1614   vat_main_t *vam = &vat_main;
1615   vat_json_node_t node;
1616
1617   vat_json_init_object (&node);
1618   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1619   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1620
1621   vat_json_print (vam->ofp, &node);
1622   vat_json_free (&node);
1623
1624   vam->retval = ntohl (mp->retval);
1625   vam->result_ready = 1;
1626 }
1627
1628
1629 static void vl_api_one_add_del_locator_set_reply_t_handler
1630   (vl_api_one_add_del_locator_set_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1646   (vl_api_one_add_del_locator_set_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1663   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->sw_if_index = ntohl (mp->sw_if_index);
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1680   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   vat_json_node_t node;
1684
1685   vat_json_init_object (&node);
1686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_gre_add_del_tunnel_reply_t_handler
1697   (vl_api_gre_add_del_tunnel_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->sw_if_index = ntohl (mp->sw_if_index);
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1714   (vl_api_gre_add_del_tunnel_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_create_vhost_user_if_reply_t_handler
1731   (vl_api_create_vhost_user_if_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_create_vhost_user_if_reply_t_handler_json
1748   (vl_api_create_vhost_user_if_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_ip_address_details_t_handler
1765   (vl_api_ip_address_details_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   static ip_address_details_t empty_ip_address_details = { {0} };
1769   ip_address_details_t *address = NULL;
1770   ip_details_t *current_ip_details = NULL;
1771   ip_details_t *details = NULL;
1772
1773   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1774
1775   if (!details || vam->current_sw_if_index >= vec_len (details)
1776       || !details[vam->current_sw_if_index].present)
1777     {
1778       errmsg ("ip address details arrived but not stored");
1779       errmsg ("ip_dump should be called first");
1780       return;
1781     }
1782
1783   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1784
1785 #define addresses (current_ip_details->addr)
1786
1787   vec_validate_init_empty (addresses, vec_len (addresses),
1788                            empty_ip_address_details);
1789
1790   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1791
1792   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1793   address->prefix_length = mp->prefix_length;
1794 #undef addresses
1795 }
1796
1797 static void vl_api_ip_address_details_t_handler_json
1798   (vl_api_ip_address_details_t * mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   vat_json_node_t *node = NULL;
1802   struct in6_addr ip6;
1803   struct in_addr ip4;
1804
1805   if (VAT_JSON_ARRAY != vam->json_tree.type)
1806     {
1807       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1808       vat_json_init_array (&vam->json_tree);
1809     }
1810   node = vat_json_array_add (&vam->json_tree);
1811
1812   vat_json_init_object (node);
1813   if (vam->is_ipv6)
1814     {
1815       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1816       vat_json_object_add_ip6 (node, "ip", ip6);
1817     }
1818   else
1819     {
1820       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1821       vat_json_object_add_ip4 (node, "ip", ip4);
1822     }
1823   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1824 }
1825
1826 static void
1827 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   static ip_details_t empty_ip_details = { 0 };
1831   ip_details_t *ip = NULL;
1832   u32 sw_if_index = ~0;
1833
1834   sw_if_index = ntohl (mp->sw_if_index);
1835
1836   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1837                            sw_if_index, empty_ip_details);
1838
1839   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1840                          sw_if_index);
1841
1842   ip->present = 1;
1843 }
1844
1845 static void
1846 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1847 {
1848   vat_main_t *vam = &vat_main;
1849
1850   if (VAT_JSON_ARRAY != vam->json_tree.type)
1851     {
1852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1853       vat_json_init_array (&vam->json_tree);
1854     }
1855   vat_json_array_add_uint (&vam->json_tree,
1856                            clib_net_to_host_u32 (mp->sw_if_index));
1857 }
1858
1859 static void vl_api_map_domain_details_t_handler_json
1860   (vl_api_map_domain_details_t * mp)
1861 {
1862   vat_json_node_t *node = NULL;
1863   vat_main_t *vam = &vat_main;
1864   struct in6_addr ip6;
1865   struct in_addr ip4;
1866
1867   if (VAT_JSON_ARRAY != vam->json_tree.type)
1868     {
1869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1870       vat_json_init_array (&vam->json_tree);
1871     }
1872
1873   node = vat_json_array_add (&vam->json_tree);
1874   vat_json_init_object (node);
1875
1876   vat_json_object_add_uint (node, "domain_index",
1877                             clib_net_to_host_u32 (mp->domain_index));
1878   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1879   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1880   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1881   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1882   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1883   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1884   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1885   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1886   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1887   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1888   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1889   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1890   vat_json_object_add_uint (node, "flags", mp->flags);
1891   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1892   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1893 }
1894
1895 static void vl_api_map_domain_details_t_handler
1896   (vl_api_map_domain_details_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899
1900   if (mp->is_translation)
1901     {
1902       print (vam->ofp,
1903              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1904              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1905              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1906              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1907              clib_net_to_host_u32 (mp->domain_index));
1908     }
1909   else
1910     {
1911       print (vam->ofp,
1912              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1913              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1914              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1915              format_ip6_address, mp->ip6_src,
1916              clib_net_to_host_u32 (mp->domain_index));
1917     }
1918   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1919          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1920          mp->is_translation ? "map-t" : "");
1921 }
1922
1923 static void vl_api_map_rule_details_t_handler_json
1924   (vl_api_map_rule_details_t * mp)
1925 {
1926   struct in6_addr ip6;
1927   vat_json_node_t *node = NULL;
1928   vat_main_t *vam = &vat_main;
1929
1930   if (VAT_JSON_ARRAY != vam->json_tree.type)
1931     {
1932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1933       vat_json_init_array (&vam->json_tree);
1934     }
1935
1936   node = vat_json_array_add (&vam->json_tree);
1937   vat_json_init_object (node);
1938
1939   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1940   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1941   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1942 }
1943
1944 static void
1945 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1949          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1950 }
1951
1952 static void
1953 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1954 {
1955   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1956           "router_addr %U host_mac %U",
1957           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1958           format_ip4_address, &mp->host_address,
1959           format_ip4_address, &mp->router_address,
1960           format_ethernet_address, mp->host_mac);
1961 }
1962
1963 static void vl_api_dhcp_compl_event_t_handler_json
1964   (vl_api_dhcp_compl_event_t * mp)
1965 {
1966   /* JSON output not supported */
1967 }
1968
1969 static void
1970 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1971                               u32 counter)
1972 {
1973   vat_main_t *vam = &vat_main;
1974   static u64 default_counter = 0;
1975
1976   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1977                            NULL);
1978   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1979                            sw_if_index, default_counter);
1980   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1981 }
1982
1983 static void
1984 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1985                                 interface_counter_t counter)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   static interface_counter_t default_counter = { 0, };
1989
1990   vec_validate_init_empty (vam->combined_interface_counters,
1991                            vnet_counter_type, NULL);
1992   vec_validate_init_empty (vam->combined_interface_counters
1993                            [vnet_counter_type], sw_if_index, default_counter);
1994   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1995 }
1996
1997 static void vl_api_vnet_interface_counters_t_handler
1998   (vl_api_vnet_interface_counters_t * mp)
1999 {
2000   /* not supported */
2001 }
2002
2003 static void vl_api_vnet_interface_counters_t_handler_json
2004   (vl_api_vnet_interface_counters_t * mp)
2005 {
2006   interface_counter_t counter;
2007   vlib_counter_t *v;
2008   u64 *v_packets;
2009   u64 packets;
2010   u32 count;
2011   u32 first_sw_if_index;
2012   int i;
2013
2014   count = ntohl (mp->count);
2015   first_sw_if_index = ntohl (mp->first_sw_if_index);
2016
2017   if (!mp->is_combined)
2018     {
2019       v_packets = (u64 *) & mp->data;
2020       for (i = 0; i < count; i++)
2021         {
2022           packets =
2023             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2024           set_simple_interface_counter (mp->vnet_counter_type,
2025                                         first_sw_if_index + i, packets);
2026           v_packets++;
2027         }
2028     }
2029   else
2030     {
2031       v = (vlib_counter_t *) & mp->data;
2032       for (i = 0; i < count; i++)
2033         {
2034           counter.packets =
2035             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2036           counter.bytes =
2037             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2038           set_combined_interface_counter (mp->vnet_counter_type,
2039                                           first_sw_if_index + i, counter);
2040           v++;
2041         }
2042     }
2043 }
2044
2045 static u32
2046 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2047 {
2048   vat_main_t *vam = &vat_main;
2049   u32 i;
2050
2051   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2052     {
2053       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2054         {
2055           return i;
2056         }
2057     }
2058   return ~0;
2059 }
2060
2061 static u32
2062 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   u32 i;
2066
2067   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2068     {
2069       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2070         {
2071           return i;
2072         }
2073     }
2074   return ~0;
2075 }
2076
2077 static void vl_api_vnet_ip4_fib_counters_t_handler
2078   (vl_api_vnet_ip4_fib_counters_t * mp)
2079 {
2080   /* not supported */
2081 }
2082
2083 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2084   (vl_api_vnet_ip4_fib_counters_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   vl_api_ip4_fib_counter_t *v;
2088   ip4_fib_counter_t *counter;
2089   struct in_addr ip4;
2090   u32 vrf_id;
2091   u32 vrf_index;
2092   u32 count;
2093   int i;
2094
2095   vrf_id = ntohl (mp->vrf_id);
2096   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2097   if (~0 == vrf_index)
2098     {
2099       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2100       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2101       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2102       vec_validate (vam->ip4_fib_counters, vrf_index);
2103       vam->ip4_fib_counters[vrf_index] = NULL;
2104     }
2105
2106   vec_free (vam->ip4_fib_counters[vrf_index]);
2107   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2108   count = ntohl (mp->count);
2109   for (i = 0; i < count; i++)
2110     {
2111       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2112       counter = &vam->ip4_fib_counters[vrf_index][i];
2113       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2114       counter->address = ip4;
2115       counter->address_length = v->address_length;
2116       counter->packets = clib_net_to_host_u64 (v->packets);
2117       counter->bytes = clib_net_to_host_u64 (v->bytes);
2118       v++;
2119     }
2120 }
2121
2122 static void vl_api_vnet_ip4_nbr_counters_t_handler
2123   (vl_api_vnet_ip4_nbr_counters_t * mp)
2124 {
2125   /* not supported */
2126 }
2127
2128 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2129   (vl_api_vnet_ip4_nbr_counters_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   vl_api_ip4_nbr_counter_t *v;
2133   ip4_nbr_counter_t *counter;
2134   u32 sw_if_index;
2135   u32 count;
2136   int i;
2137
2138   sw_if_index = ntohl (mp->sw_if_index);
2139   count = ntohl (mp->count);
2140   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2141
2142   if (mp->begin)
2143     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2144
2145   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2146   for (i = 0; i < count; i++)
2147     {
2148       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2149       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2150       counter->address.s_addr = v->address;
2151       counter->packets = clib_net_to_host_u64 (v->packets);
2152       counter->bytes = clib_net_to_host_u64 (v->bytes);
2153       counter->linkt = v->link_type;
2154       v++;
2155     }
2156 }
2157
2158 static void vl_api_vnet_ip6_fib_counters_t_handler
2159   (vl_api_vnet_ip6_fib_counters_t * mp)
2160 {
2161   /* not supported */
2162 }
2163
2164 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2165   (vl_api_vnet_ip6_fib_counters_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vl_api_ip6_fib_counter_t *v;
2169   ip6_fib_counter_t *counter;
2170   struct in6_addr ip6;
2171   u32 vrf_id;
2172   u32 vrf_index;
2173   u32 count;
2174   int i;
2175
2176   vrf_id = ntohl (mp->vrf_id);
2177   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2178   if (~0 == vrf_index)
2179     {
2180       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2181       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2182       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2183       vec_validate (vam->ip6_fib_counters, vrf_index);
2184       vam->ip6_fib_counters[vrf_index] = NULL;
2185     }
2186
2187   vec_free (vam->ip6_fib_counters[vrf_index]);
2188   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2189   count = ntohl (mp->count);
2190   for (i = 0; i < count; i++)
2191     {
2192       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2193       counter = &vam->ip6_fib_counters[vrf_index][i];
2194       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2195       counter->address = ip6;
2196       counter->address_length = v->address_length;
2197       counter->packets = clib_net_to_host_u64 (v->packets);
2198       counter->bytes = clib_net_to_host_u64 (v->bytes);
2199       v++;
2200     }
2201 }
2202
2203 static void vl_api_vnet_ip6_nbr_counters_t_handler
2204   (vl_api_vnet_ip6_nbr_counters_t * mp)
2205 {
2206   /* not supported */
2207 }
2208
2209 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2210   (vl_api_vnet_ip6_nbr_counters_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   vl_api_ip6_nbr_counter_t *v;
2214   ip6_nbr_counter_t *counter;
2215   struct in6_addr ip6;
2216   u32 sw_if_index;
2217   u32 count;
2218   int i;
2219
2220   sw_if_index = ntohl (mp->sw_if_index);
2221   count = ntohl (mp->count);
2222   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2223
2224   if (mp->begin)
2225     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2226
2227   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2228   for (i = 0; i < count; i++)
2229     {
2230       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2231       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2232       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2233       counter->address = ip6;
2234       counter->packets = clib_net_to_host_u64 (v->packets);
2235       counter->bytes = clib_net_to_host_u64 (v->bytes);
2236       v++;
2237     }
2238 }
2239
2240 static void vl_api_get_first_msg_id_reply_t_handler
2241   (vl_api_get_first_msg_id_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   i32 retval = ntohl (mp->retval);
2245
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->result_ready = 1;
2254     }
2255   if (retval >= 0)
2256     {
2257       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2258     }
2259 }
2260
2261 static void vl_api_get_first_msg_id_reply_t_handler_json
2262   (vl_api_get_first_msg_id_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t node;
2266
2267   vat_json_init_object (&node);
2268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269   vat_json_object_add_uint (&node, "first_msg_id",
2270                             (uint) ntohs (mp->first_msg_id));
2271
2272   vat_json_print (vam->ofp, &node);
2273   vat_json_free (&node);
2274
2275   vam->retval = ntohl (mp->retval);
2276   vam->result_ready = 1;
2277 }
2278
2279 static void vl_api_get_node_graph_reply_t_handler
2280   (vl_api_get_node_graph_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   api_main_t *am = &api_main;
2284   i32 retval = ntohl (mp->retval);
2285   u8 *pvt_copy, *reply;
2286   void *oldheap;
2287   vlib_node_t *node;
2288   int i;
2289
2290   if (vam->async_mode)
2291     {
2292       vam->async_errors += (retval < 0);
2293     }
2294   else
2295     {
2296       vam->retval = retval;
2297       vam->result_ready = 1;
2298     }
2299
2300   /* "Should never happen..." */
2301   if (retval != 0)
2302     return;
2303
2304   reply = (u8 *) (mp->reply_in_shmem);
2305   pvt_copy = vec_dup (reply);
2306
2307   /* Toss the shared-memory original... */
2308   pthread_mutex_lock (&am->vlib_rp->mutex);
2309   oldheap = svm_push_data_heap (am->vlib_rp);
2310
2311   vec_free (reply);
2312
2313   svm_pop_heap (oldheap);
2314   pthread_mutex_unlock (&am->vlib_rp->mutex);
2315
2316   if (vam->graph_nodes)
2317     {
2318       hash_free (vam->graph_node_index_by_name);
2319
2320       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2321         {
2322           node = vam->graph_nodes[i];
2323           vec_free (node->name);
2324           vec_free (node->next_nodes);
2325           vec_free (node);
2326         }
2327       vec_free (vam->graph_nodes);
2328     }
2329
2330   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2331   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2332   vec_free (pvt_copy);
2333
2334   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2335     {
2336       node = vam->graph_nodes[i];
2337       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2338     }
2339 }
2340
2341 static void vl_api_get_node_graph_reply_t_handler_json
2342   (vl_api_get_node_graph_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   api_main_t *am = &api_main;
2346   void *oldheap;
2347   vat_json_node_t node;
2348   u8 *reply;
2349
2350   /* $$$$ make this real? */
2351   vat_json_init_object (&node);
2352   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2353   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2354
2355   reply = (u8 *) (mp->reply_in_shmem);
2356
2357   /* Toss the shared-memory original... */
2358   pthread_mutex_lock (&am->vlib_rp->mutex);
2359   oldheap = svm_push_data_heap (am->vlib_rp);
2360
2361   vec_free (reply);
2362
2363   svm_pop_heap (oldheap);
2364   pthread_mutex_unlock (&am->vlib_rp->mutex);
2365
2366   vat_json_print (vam->ofp, &node);
2367   vat_json_free (&node);
2368
2369   vam->retval = ntohl (mp->retval);
2370   vam->result_ready = 1;
2371 }
2372
2373 static void
2374 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   u8 *s = 0;
2378
2379   if (mp->local)
2380     {
2381       s = format (s, "%=16d%=16d%=16d",
2382                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2383     }
2384   else
2385     {
2386       s = format (s, "%=16U%=16d%=16d",
2387                   mp->is_ipv6 ? format_ip6_address :
2388                   format_ip4_address,
2389                   mp->ip_address, mp->priority, mp->weight);
2390     }
2391
2392   print (vam->ofp, "%v", s);
2393   vec_free (s);
2394 }
2395
2396 static void
2397 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   vat_json_node_t *node = NULL;
2401   struct in6_addr ip6;
2402   struct in_addr ip4;
2403
2404   if (VAT_JSON_ARRAY != vam->json_tree.type)
2405     {
2406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2407       vat_json_init_array (&vam->json_tree);
2408     }
2409   node = vat_json_array_add (&vam->json_tree);
2410   vat_json_init_object (node);
2411
2412   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2413   vat_json_object_add_uint (node, "priority", mp->priority);
2414   vat_json_object_add_uint (node, "weight", mp->weight);
2415
2416   if (mp->local)
2417     vat_json_object_add_uint (node, "sw_if_index",
2418                               clib_net_to_host_u32 (mp->sw_if_index));
2419   else
2420     {
2421       if (mp->is_ipv6)
2422         {
2423           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2424           vat_json_object_add_ip6 (node, "address", ip6);
2425         }
2426       else
2427         {
2428           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2429           vat_json_object_add_ip4 (node, "address", ip4);
2430         }
2431     }
2432 }
2433
2434 static void
2435 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2436                                           mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   u8 *ls_name = 0;
2440
2441   ls_name = format (0, "%s", mp->ls_name);
2442
2443   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2444          ls_name);
2445   vec_free (ls_name);
2446 }
2447
2448 static void
2449   vl_api_one_locator_set_details_t_handler_json
2450   (vl_api_one_locator_set_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t *node = 0;
2454   u8 *ls_name = 0;
2455
2456   ls_name = format (0, "%s", mp->ls_name);
2457   vec_add1 (ls_name, 0);
2458
2459   if (VAT_JSON_ARRAY != vam->json_tree.type)
2460     {
2461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2462       vat_json_init_array (&vam->json_tree);
2463     }
2464   node = vat_json_array_add (&vam->json_tree);
2465
2466   vat_json_init_object (node);
2467   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2468   vat_json_object_add_uint (node, "ls_index",
2469                             clib_net_to_host_u32 (mp->ls_index));
2470   vec_free (ls_name);
2471 }
2472
2473 static u8 *
2474 format_lisp_flat_eid (u8 * s, va_list * args)
2475 {
2476   u32 type = va_arg (*args, u32);
2477   u8 *eid = va_arg (*args, u8 *);
2478   u32 eid_len = va_arg (*args, u32);
2479
2480   switch (type)
2481     {
2482     case 0:
2483       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2484     case 1:
2485       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2486     case 2:
2487       return format (s, "%U", format_ethernet_address, eid);
2488     }
2489   return 0;
2490 }
2491
2492 static u8 *
2493 format_lisp_eid_vat (u8 * s, va_list * args)
2494 {
2495   u32 type = va_arg (*args, u32);
2496   u8 *eid = va_arg (*args, u8 *);
2497   u32 eid_len = va_arg (*args, u32);
2498   u8 *seid = va_arg (*args, u8 *);
2499   u32 seid_len = va_arg (*args, u32);
2500   u32 is_src_dst = va_arg (*args, u32);
2501
2502   if (is_src_dst)
2503     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2504
2505   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2506
2507   return s;
2508 }
2509
2510 static void
2511 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *s = 0, *eid = 0;
2515
2516   if (~0 == mp->locator_set_index)
2517     s = format (0, "action: %d", mp->action);
2518   else
2519     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2520
2521   eid = format (0, "%U", format_lisp_eid_vat,
2522                 mp->eid_type,
2523                 mp->eid,
2524                 mp->eid_prefix_len,
2525                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2526   vec_add1 (eid, 0);
2527
2528   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2529          clib_net_to_host_u32 (mp->vni),
2530          eid,
2531          mp->is_local ? "local" : "remote",
2532          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2533          clib_net_to_host_u16 (mp->key_id), mp->key);
2534
2535   vec_free (s);
2536   vec_free (eid);
2537 }
2538
2539 static void
2540 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2541                                              * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = 0;
2545   u8 *eid = 0;
2546
2547   if (VAT_JSON_ARRAY != vam->json_tree.type)
2548     {
2549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2550       vat_json_init_array (&vam->json_tree);
2551     }
2552   node = vat_json_array_add (&vam->json_tree);
2553
2554   vat_json_init_object (node);
2555   if (~0 == mp->locator_set_index)
2556     vat_json_object_add_uint (node, "action", mp->action);
2557   else
2558     vat_json_object_add_uint (node, "locator_set_index",
2559                               clib_net_to_host_u32 (mp->locator_set_index));
2560
2561   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2562   eid = format (0, "%U", format_lisp_eid_vat,
2563                 mp->eid_type,
2564                 mp->eid,
2565                 mp->eid_prefix_len,
2566                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2567   vec_add1 (eid, 0);
2568   vat_json_object_add_string_copy (node, "eid", eid);
2569   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2570   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2571   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2572
2573   if (mp->key_id)
2574     {
2575       vat_json_object_add_uint (node, "key_id",
2576                                 clib_net_to_host_u16 (mp->key_id));
2577       vat_json_object_add_string_copy (node, "key", mp->key);
2578     }
2579   vec_free (eid);
2580 }
2581
2582 static void
2583   vl_api_one_eid_table_map_details_t_handler
2584   (vl_api_one_eid_table_map_details_t * mp)
2585 {
2586   vat_main_t *vam = &vat_main;
2587
2588   u8 *line = format (0, "%=10d%=10d",
2589                      clib_net_to_host_u32 (mp->vni),
2590                      clib_net_to_host_u32 (mp->dp_table));
2591   print (vam->ofp, "%v", line);
2592   vec_free (line);
2593 }
2594
2595 static void
2596   vl_api_one_eid_table_map_details_t_handler_json
2597   (vl_api_one_eid_table_map_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = NULL;
2601
2602   if (VAT_JSON_ARRAY != vam->json_tree.type)
2603     {
2604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2605       vat_json_init_array (&vam->json_tree);
2606     }
2607   node = vat_json_array_add (&vam->json_tree);
2608   vat_json_init_object (node);
2609   vat_json_object_add_uint (node, "dp_table",
2610                             clib_net_to_host_u32 (mp->dp_table));
2611   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2612 }
2613
2614 static void
2615   vl_api_one_eid_table_vni_details_t_handler
2616   (vl_api_one_eid_table_vni_details_t * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2621   print (vam->ofp, "%v", line);
2622   vec_free (line);
2623 }
2624
2625 static void
2626   vl_api_one_eid_table_vni_details_t_handler_json
2627   (vl_api_one_eid_table_vni_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631
2632   if (VAT_JSON_ARRAY != vam->json_tree.type)
2633     {
2634       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2635       vat_json_init_array (&vam->json_tree);
2636     }
2637   node = vat_json_array_add (&vam->json_tree);
2638   vat_json_init_object (node);
2639   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2640 }
2641
2642 static void
2643   vl_api_show_one_map_register_state_reply_t_handler
2644   (vl_api_show_one_map_register_state_reply_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   int retval = clib_net_to_host_u32 (mp->retval);
2648
2649   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2650
2651   vam->retval = retval;
2652   vam->result_ready = 1;
2653 }
2654
2655 static void
2656   vl_api_show_one_map_register_state_reply_t_handler_json
2657   (vl_api_show_one_map_register_state_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t _node, *node = &_node;
2661   int retval = clib_net_to_host_u32 (mp->retval);
2662
2663   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2664
2665   vat_json_init_object (node);
2666   vat_json_object_add_string_copy (node, "state", s);
2667
2668   vat_json_print (vam->ofp, node);
2669   vat_json_free (node);
2670
2671   vam->retval = retval;
2672   vam->result_ready = 1;
2673   vec_free (s);
2674 }
2675
2676 static void
2677   vl_api_show_one_rloc_probe_state_reply_t_handler
2678   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   int retval = clib_net_to_host_u32 (mp->retval);
2682
2683   if (retval)
2684     goto end;
2685
2686   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2687 end:
2688   vam->retval = retval;
2689   vam->result_ready = 1;
2690 }
2691
2692 static void
2693   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2694   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   vat_json_node_t _node, *node = &_node;
2698   int retval = clib_net_to_host_u32 (mp->retval);
2699
2700   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2701   vat_json_init_object (node);
2702   vat_json_object_add_string_copy (node, "state", s);
2703
2704   vat_json_print (vam->ofp, node);
2705   vat_json_free (node);
2706
2707   vam->retval = retval;
2708   vam->result_ready = 1;
2709   vec_free (s);
2710 }
2711
2712 static void
2713 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2714 {
2715   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2716   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2717 }
2718
2719 static void
2720   gpe_fwd_entries_get_reply_t_net_to_host
2721   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2722 {
2723   u32 i;
2724
2725   mp->count = clib_net_to_host_u32 (mp->count);
2726   for (i = 0; i < mp->count; i++)
2727     {
2728       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2729     }
2730 }
2731
2732 static void
2733   vl_api_gpe_fwd_entry_path_details_t_handler
2734   (vl_api_gpe_fwd_entry_path_details_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2738
2739   if (mp->lcl_loc.is_ip4)
2740     format_ip_address_fcn = format_ip4_address;
2741   else
2742     format_ip_address_fcn = format_ip6_address;
2743
2744   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2745          format_ip_address_fcn, &mp->lcl_loc,
2746          format_ip_address_fcn, &mp->rmt_loc);
2747 }
2748
2749 static void
2750 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2751 {
2752   struct in6_addr ip6;
2753   struct in_addr ip4;
2754
2755   if (loc->is_ip4)
2756     {
2757       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2758       vat_json_object_add_ip4 (n, "address", ip4);
2759     }
2760   else
2761     {
2762       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2763       vat_json_object_add_ip6 (n, "address", ip6);
2764     }
2765   vat_json_object_add_uint (n, "weight", loc->weight);
2766 }
2767
2768 static void
2769   vl_api_gpe_fwd_entry_path_details_t_handler_json
2770   (vl_api_gpe_fwd_entry_path_details_t * mp)
2771 {
2772   vat_main_t *vam = &vat_main;
2773   vat_json_node_t *node = NULL;
2774   vat_json_node_t *loc_node;
2775
2776   if (VAT_JSON_ARRAY != vam->json_tree.type)
2777     {
2778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2779       vat_json_init_array (&vam->json_tree);
2780     }
2781   node = vat_json_array_add (&vam->json_tree);
2782   vat_json_init_object (node);
2783
2784   loc_node = vat_json_object_add (node, "local_locator");
2785   vat_json_init_object (loc_node);
2786   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2787
2788   loc_node = vat_json_object_add (node, "remote_locator");
2789   vat_json_init_object (loc_node);
2790   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2791 }
2792
2793 static void
2794   vl_api_gpe_fwd_entries_get_reply_t_handler
2795   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2796 {
2797   vat_main_t *vam = &vat_main;
2798   u32 i;
2799   int retval = clib_net_to_host_u32 (mp->retval);
2800   vl_api_gpe_fwd_entry_t *e;
2801
2802   if (retval)
2803     goto end;
2804
2805   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2806
2807   for (i = 0; i < mp->count; i++)
2808     {
2809       e = &mp->entries[i];
2810       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2811              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2812              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2813     }
2814
2815 end:
2816   vam->retval = retval;
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2822   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2823 {
2824   u8 *s = 0;
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t *e = 0, root;
2827   u32 i;
2828   int retval = clib_net_to_host_u32 (mp->retval);
2829   vl_api_gpe_fwd_entry_t *fwd;
2830
2831   if (retval)
2832     goto end;
2833
2834   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2835   vat_json_init_array (&root);
2836
2837   for (i = 0; i < mp->count; i++)
2838     {
2839       e = vat_json_array_add (&root);
2840       fwd = &mp->entries[i];
2841
2842       vat_json_init_object (e);
2843       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2844       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2845
2846       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2847                   fwd->leid_prefix_len);
2848       vec_add1 (s, 0);
2849       vat_json_object_add_string_copy (e, "leid", s);
2850       vec_free (s);
2851
2852       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2853                   fwd->reid_prefix_len);
2854       vec_add1 (s, 0);
2855       vat_json_object_add_string_copy (e, "reid", s);
2856       vec_free (s);
2857     }
2858
2859   vat_json_print (vam->ofp, &root);
2860   vat_json_free (&root);
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_one_adjacencies_get_reply_t_handler
2869   (vl_api_one_adjacencies_get_reply_t * mp)
2870 {
2871   vat_main_t *vam = &vat_main;
2872   u32 i, n;
2873   int retval = clib_net_to_host_u32 (mp->retval);
2874   vl_api_one_adjacency_t *a;
2875
2876   if (retval)
2877     goto end;
2878
2879   n = clib_net_to_host_u32 (mp->count);
2880
2881   for (i = 0; i < n; i++)
2882     {
2883       a = &mp->adjacencies[i];
2884       print (vam->ofp, "%U %40U",
2885              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2886              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2887     }
2888
2889 end:
2890   vam->retval = retval;
2891   vam->result_ready = 1;
2892 }
2893
2894 static void
2895   vl_api_one_adjacencies_get_reply_t_handler_json
2896   (vl_api_one_adjacencies_get_reply_t * mp)
2897 {
2898   u8 *s = 0;
2899   vat_main_t *vam = &vat_main;
2900   vat_json_node_t *e = 0, root;
2901   u32 i, n;
2902   int retval = clib_net_to_host_u32 (mp->retval);
2903   vl_api_one_adjacency_t *a;
2904
2905   if (retval)
2906     goto end;
2907
2908   n = clib_net_to_host_u32 (mp->count);
2909   vat_json_init_array (&root);
2910
2911   for (i = 0; i < n; i++)
2912     {
2913       e = vat_json_array_add (&root);
2914       a = &mp->adjacencies[i];
2915
2916       vat_json_init_object (e);
2917       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2918                   a->leid_prefix_len);
2919       vec_add1 (s, 0);
2920       vat_json_object_add_string_copy (e, "leid", s);
2921       vec_free (s);
2922
2923       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2924                   a->reid_prefix_len);
2925       vec_add1 (s, 0);
2926       vat_json_object_add_string_copy (e, "reid", s);
2927       vec_free (s);
2928     }
2929
2930   vat_json_print (vam->ofp, &root);
2931   vat_json_free (&root);
2932
2933 end:
2934   vam->retval = retval;
2935   vam->result_ready = 1;
2936 }
2937
2938 static void
2939 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942
2943   print (vam->ofp, "%=20U",
2944          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2945          mp->ip_address);
2946 }
2947
2948 static void
2949   vl_api_one_map_server_details_t_handler_json
2950   (vl_api_one_map_server_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   vat_json_node_t *node = NULL;
2954   struct in6_addr ip6;
2955   struct in_addr ip4;
2956
2957   if (VAT_JSON_ARRAY != vam->json_tree.type)
2958     {
2959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2960       vat_json_init_array (&vam->json_tree);
2961     }
2962   node = vat_json_array_add (&vam->json_tree);
2963
2964   vat_json_init_object (node);
2965   if (mp->is_ipv6)
2966     {
2967       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2968       vat_json_object_add_ip6 (node, "map-server", ip6);
2969     }
2970   else
2971     {
2972       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2973       vat_json_object_add_ip4 (node, "map-server", ip4);
2974     }
2975 }
2976
2977 static void
2978 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
2979                                            * mp)
2980 {
2981   vat_main_t *vam = &vat_main;
2982
2983   print (vam->ofp, "%=20U",
2984          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2985          mp->ip_address);
2986 }
2987
2988 static void
2989   vl_api_one_map_resolver_details_t_handler_json
2990   (vl_api_one_map_resolver_details_t * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   vat_json_node_t *node = NULL;
2994   struct in6_addr ip6;
2995   struct in_addr ip4;
2996
2997   if (VAT_JSON_ARRAY != vam->json_tree.type)
2998     {
2999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3000       vat_json_init_array (&vam->json_tree);
3001     }
3002   node = vat_json_array_add (&vam->json_tree);
3003
3004   vat_json_init_object (node);
3005   if (mp->is_ipv6)
3006     {
3007       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3008       vat_json_object_add_ip6 (node, "map resolver", ip6);
3009     }
3010   else
3011     {
3012       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3013       vat_json_object_add_ip4 (node, "map resolver", ip4);
3014     }
3015 }
3016
3017 static void
3018 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   i32 retval = ntohl (mp->retval);
3022
3023   if (0 <= retval)
3024     {
3025       print (vam->ofp, "feature: %s\ngpe: %s",
3026              mp->feature_status ? "enabled" : "disabled",
3027              mp->gpe_status ? "enabled" : "disabled");
3028     }
3029
3030   vam->retval = retval;
3031   vam->result_ready = 1;
3032 }
3033
3034 static void
3035   vl_api_show_one_status_reply_t_handler_json
3036   (vl_api_show_one_status_reply_t * mp)
3037 {
3038   vat_main_t *vam = &vat_main;
3039   vat_json_node_t node;
3040   u8 *gpe_status = NULL;
3041   u8 *feature_status = NULL;
3042
3043   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3044   feature_status = format (0, "%s",
3045                            mp->feature_status ? "enabled" : "disabled");
3046   vec_add1 (gpe_status, 0);
3047   vec_add1 (feature_status, 0);
3048
3049   vat_json_init_object (&node);
3050   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3051   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3052
3053   vec_free (gpe_status);
3054   vec_free (feature_status);
3055
3056   vat_json_print (vam->ofp, &node);
3057   vat_json_free (&node);
3058
3059   vam->retval = ntohl (mp->retval);
3060   vam->result_ready = 1;
3061 }
3062
3063 static void
3064   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3065   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3066 {
3067   vat_main_t *vam = &vat_main;
3068   i32 retval = ntohl (mp->retval);
3069
3070   if (retval >= 0)
3071     {
3072       print (vam->ofp, "%=20s", mp->locator_set_name);
3073     }
3074
3075   vam->retval = retval;
3076   vam->result_ready = 1;
3077 }
3078
3079 static void
3080   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3081   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t *node = NULL;
3085
3086   if (VAT_JSON_ARRAY != vam->json_tree.type)
3087     {
3088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3089       vat_json_init_array (&vam->json_tree);
3090     }
3091   node = vat_json_array_add (&vam->json_tree);
3092
3093   vat_json_init_object (node);
3094   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3095
3096   vat_json_print (vam->ofp, node);
3097   vat_json_free (node);
3098
3099   vam->retval = ntohl (mp->retval);
3100   vam->result_ready = 1;
3101 }
3102
3103 static u8 *
3104 format_lisp_map_request_mode (u8 * s, va_list * args)
3105 {
3106   u32 mode = va_arg (*args, u32);
3107
3108   switch (mode)
3109     {
3110     case 0:
3111       return format (0, "dst-only");
3112     case 1:
3113       return format (0, "src-dst");
3114     }
3115   return 0;
3116 }
3117
3118 static void
3119   vl_api_show_one_map_request_mode_reply_t_handler
3120   (vl_api_show_one_map_request_mode_reply_t * mp)
3121 {
3122   vat_main_t *vam = &vat_main;
3123   i32 retval = ntohl (mp->retval);
3124
3125   if (0 <= retval)
3126     {
3127       u32 mode = mp->mode;
3128       print (vam->ofp, "map_request_mode: %U",
3129              format_lisp_map_request_mode, mode);
3130     }
3131
3132   vam->retval = retval;
3133   vam->result_ready = 1;
3134 }
3135
3136 static void
3137   vl_api_show_one_map_request_mode_reply_t_handler_json
3138   (vl_api_show_one_map_request_mode_reply_t * mp)
3139 {
3140   vat_main_t *vam = &vat_main;
3141   vat_json_node_t node;
3142   u8 *s = 0;
3143   u32 mode;
3144
3145   mode = mp->mode;
3146   s = format (0, "%U", format_lisp_map_request_mode, mode);
3147   vec_add1 (s, 0);
3148
3149   vat_json_init_object (&node);
3150   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3151   vat_json_print (vam->ofp, &node);
3152   vat_json_free (&node);
3153
3154   vec_free (s);
3155   vam->retval = ntohl (mp->retval);
3156   vam->result_ready = 1;
3157 }
3158
3159 static void
3160 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3161 {
3162   vat_main_t *vam = &vat_main;
3163   i32 retval = ntohl (mp->retval);
3164
3165   if (0 <= retval)
3166     {
3167       print (vam->ofp, "%-20s%-16s",
3168              mp->status ? "enabled" : "disabled",
3169              mp->status ? (char *) mp->locator_set_name : "");
3170     }
3171
3172   vam->retval = retval;
3173   vam->result_ready = 1;
3174 }
3175
3176 static void
3177 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3178 {
3179   vat_main_t *vam = &vat_main;
3180   vat_json_node_t node;
3181   u8 *status = 0;
3182
3183   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3184   vec_add1 (status, 0);
3185
3186   vat_json_init_object (&node);
3187   vat_json_object_add_string_copy (&node, "status", status);
3188   if (mp->status)
3189     {
3190       vat_json_object_add_string_copy (&node, "locator_set",
3191                                        mp->locator_set_name);
3192     }
3193
3194   vec_free (status);
3195
3196   vat_json_print (vam->ofp, &node);
3197   vat_json_free (&node);
3198
3199   vam->retval = ntohl (mp->retval);
3200   vam->result_ready = 1;
3201 }
3202
3203 static u8 *
3204 format_policer_type (u8 * s, va_list * va)
3205 {
3206   u32 i = va_arg (*va, u32);
3207
3208   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3209     s = format (s, "1r2c");
3210   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3211     s = format (s, "1r3c");
3212   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3213     s = format (s, "2r3c-2698");
3214   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3215     s = format (s, "2r3c-4115");
3216   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3217     s = format (s, "2r3c-mef5cf1");
3218   else
3219     s = format (s, "ILLEGAL");
3220   return s;
3221 }
3222
3223 static u8 *
3224 format_policer_rate_type (u8 * s, va_list * va)
3225 {
3226   u32 i = va_arg (*va, u32);
3227
3228   if (i == SSE2_QOS_RATE_KBPS)
3229     s = format (s, "kbps");
3230   else if (i == SSE2_QOS_RATE_PPS)
3231     s = format (s, "pps");
3232   else
3233     s = format (s, "ILLEGAL");
3234   return s;
3235 }
3236
3237 static u8 *
3238 format_policer_round_type (u8 * s, va_list * va)
3239 {
3240   u32 i = va_arg (*va, u32);
3241
3242   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3243     s = format (s, "closest");
3244   else if (i == SSE2_QOS_ROUND_TO_UP)
3245     s = format (s, "up");
3246   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3247     s = format (s, "down");
3248   else
3249     s = format (s, "ILLEGAL");
3250   return s;
3251 }
3252
3253 static u8 *
3254 format_policer_action_type (u8 * s, va_list * va)
3255 {
3256   u32 i = va_arg (*va, u32);
3257
3258   if (i == SSE2_QOS_ACTION_DROP)
3259     s = format (s, "drop");
3260   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3261     s = format (s, "transmit");
3262   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3263     s = format (s, "mark-and-transmit");
3264   else
3265     s = format (s, "ILLEGAL");
3266   return s;
3267 }
3268
3269 static u8 *
3270 format_dscp (u8 * s, va_list * va)
3271 {
3272   u32 i = va_arg (*va, u32);
3273   char *t = 0;
3274
3275   switch (i)
3276     {
3277 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3278       foreach_vnet_dscp
3279 #undef _
3280     default:
3281       return format (s, "ILLEGAL");
3282     }
3283   s = format (s, "%s", t);
3284   return s;
3285 }
3286
3287 static void
3288 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3292
3293   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3294     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3295   else
3296     conform_dscp_str = format (0, "");
3297
3298   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3299     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3300   else
3301     exceed_dscp_str = format (0, "");
3302
3303   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3304     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3305   else
3306     violate_dscp_str = format (0, "");
3307
3308   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3309          "rate type %U, round type %U, %s rate, %s color-aware, "
3310          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3311          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3312          "conform action %U%s, exceed action %U%s, violate action %U%s",
3313          mp->name,
3314          format_policer_type, mp->type,
3315          ntohl (mp->cir),
3316          ntohl (mp->eir),
3317          clib_net_to_host_u64 (mp->cb),
3318          clib_net_to_host_u64 (mp->eb),
3319          format_policer_rate_type, mp->rate_type,
3320          format_policer_round_type, mp->round_type,
3321          mp->single_rate ? "single" : "dual",
3322          mp->color_aware ? "is" : "not",
3323          ntohl (mp->cir_tokens_per_period),
3324          ntohl (mp->pir_tokens_per_period),
3325          ntohl (mp->scale),
3326          ntohl (mp->current_limit),
3327          ntohl (mp->current_bucket),
3328          ntohl (mp->extended_limit),
3329          ntohl (mp->extended_bucket),
3330          clib_net_to_host_u64 (mp->last_update_time),
3331          format_policer_action_type, mp->conform_action_type,
3332          conform_dscp_str,
3333          format_policer_action_type, mp->exceed_action_type,
3334          exceed_dscp_str,
3335          format_policer_action_type, mp->violate_action_type,
3336          violate_dscp_str);
3337
3338   vec_free (conform_dscp_str);
3339   vec_free (exceed_dscp_str);
3340   vec_free (violate_dscp_str);
3341 }
3342
3343 static void vl_api_policer_details_t_handler_json
3344   (vl_api_policer_details_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   vat_json_node_t *node;
3348   u8 *rate_type_str, *round_type_str, *type_str;
3349   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3350
3351   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3352   round_type_str =
3353     format (0, "%U", format_policer_round_type, mp->round_type);
3354   type_str = format (0, "%U", format_policer_type, mp->type);
3355   conform_action_str = format (0, "%U", format_policer_action_type,
3356                                mp->conform_action_type);
3357   exceed_action_str = format (0, "%U", format_policer_action_type,
3358                               mp->exceed_action_type);
3359   violate_action_str = format (0, "%U", format_policer_action_type,
3360                                mp->violate_action_type);
3361
3362   if (VAT_JSON_ARRAY != vam->json_tree.type)
3363     {
3364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3365       vat_json_init_array (&vam->json_tree);
3366     }
3367   node = vat_json_array_add (&vam->json_tree);
3368
3369   vat_json_init_object (node);
3370   vat_json_object_add_string_copy (node, "name", mp->name);
3371   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3372   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3373   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3374   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3375   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3376   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3377   vat_json_object_add_string_copy (node, "type", type_str);
3378   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3379   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3380   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3381   vat_json_object_add_uint (node, "cir_tokens_per_period",
3382                             ntohl (mp->cir_tokens_per_period));
3383   vat_json_object_add_uint (node, "eir_tokens_per_period",
3384                             ntohl (mp->pir_tokens_per_period));
3385   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3386   vat_json_object_add_uint (node, "current_bucket",
3387                             ntohl (mp->current_bucket));
3388   vat_json_object_add_uint (node, "extended_limit",
3389                             ntohl (mp->extended_limit));
3390   vat_json_object_add_uint (node, "extended_bucket",
3391                             ntohl (mp->extended_bucket));
3392   vat_json_object_add_uint (node, "last_update_time",
3393                             ntohl (mp->last_update_time));
3394   vat_json_object_add_string_copy (node, "conform_action",
3395                                    conform_action_str);
3396   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3397     {
3398       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3399       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3400       vec_free (dscp_str);
3401     }
3402   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3403   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3404     {
3405       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3406       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3407       vec_free (dscp_str);
3408     }
3409   vat_json_object_add_string_copy (node, "violate_action",
3410                                    violate_action_str);
3411   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3412     {
3413       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3414       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3415       vec_free (dscp_str);
3416     }
3417
3418   vec_free (rate_type_str);
3419   vec_free (round_type_str);
3420   vec_free (type_str);
3421   vec_free (conform_action_str);
3422   vec_free (exceed_action_str);
3423   vec_free (violate_action_str);
3424 }
3425
3426 static void
3427 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3428                                            mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int i, count = ntohl (mp->count);
3432
3433   if (count > 0)
3434     print (vam->ofp, "classify table ids (%d) : ", count);
3435   for (i = 0; i < count; i++)
3436     {
3437       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3438       print (vam->ofp, (i < count - 1) ? "," : "");
3439     }
3440   vam->retval = ntohl (mp->retval);
3441   vam->result_ready = 1;
3442 }
3443
3444 static void
3445   vl_api_classify_table_ids_reply_t_handler_json
3446   (vl_api_classify_table_ids_reply_t * mp)
3447 {
3448   vat_main_t *vam = &vat_main;
3449   int i, count = ntohl (mp->count);
3450
3451   if (count > 0)
3452     {
3453       vat_json_node_t node;
3454
3455       vat_json_init_object (&node);
3456       for (i = 0; i < count; i++)
3457         {
3458           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3459         }
3460       vat_json_print (vam->ofp, &node);
3461       vat_json_free (&node);
3462     }
3463   vam->retval = ntohl (mp->retval);
3464   vam->result_ready = 1;
3465 }
3466
3467 static void
3468   vl_api_classify_table_by_interface_reply_t_handler
3469   (vl_api_classify_table_by_interface_reply_t * mp)
3470 {
3471   vat_main_t *vam = &vat_main;
3472   u32 table_id;
3473
3474   table_id = ntohl (mp->l2_table_id);
3475   if (table_id != ~0)
3476     print (vam->ofp, "l2 table id : %d", table_id);
3477   else
3478     print (vam->ofp, "l2 table id : No input ACL tables configured");
3479   table_id = ntohl (mp->ip4_table_id);
3480   if (table_id != ~0)
3481     print (vam->ofp, "ip4 table id : %d", table_id);
3482   else
3483     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3484   table_id = ntohl (mp->ip6_table_id);
3485   if (table_id != ~0)
3486     print (vam->ofp, "ip6 table id : %d", table_id);
3487   else
3488     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3489   vam->retval = ntohl (mp->retval);
3490   vam->result_ready = 1;
3491 }
3492
3493 static void
3494   vl_api_classify_table_by_interface_reply_t_handler_json
3495   (vl_api_classify_table_by_interface_reply_t * mp)
3496 {
3497   vat_main_t *vam = &vat_main;
3498   vat_json_node_t node;
3499
3500   vat_json_init_object (&node);
3501
3502   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3503   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3504   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3505
3506   vat_json_print (vam->ofp, &node);
3507   vat_json_free (&node);
3508
3509   vam->retval = ntohl (mp->retval);
3510   vam->result_ready = 1;
3511 }
3512
3513 static void vl_api_policer_add_del_reply_t_handler
3514   (vl_api_policer_add_del_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   i32 retval = ntohl (mp->retval);
3518   if (vam->async_mode)
3519     {
3520       vam->async_errors += (retval < 0);
3521     }
3522   else
3523     {
3524       vam->retval = retval;
3525       vam->result_ready = 1;
3526       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3527         /*
3528          * Note: this is just barely thread-safe, depends on
3529          * the main thread spinning waiting for an answer...
3530          */
3531         errmsg ("policer index %d", ntohl (mp->policer_index));
3532     }
3533 }
3534
3535 static void vl_api_policer_add_del_reply_t_handler_json
3536   (vl_api_policer_add_del_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   vat_json_node_t node;
3540
3541   vat_json_init_object (&node);
3542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3543   vat_json_object_add_uint (&node, "policer_index",
3544                             ntohl (mp->policer_index));
3545
3546   vat_json_print (vam->ofp, &node);
3547   vat_json_free (&node);
3548
3549   vam->retval = ntohl (mp->retval);
3550   vam->result_ready = 1;
3551 }
3552
3553 /* Format hex dump. */
3554 u8 *
3555 format_hex_bytes (u8 * s, va_list * va)
3556 {
3557   u8 *bytes = va_arg (*va, u8 *);
3558   int n_bytes = va_arg (*va, int);
3559   uword i;
3560
3561   /* Print short or long form depending on byte count. */
3562   uword short_form = n_bytes <= 32;
3563   uword indent = format_get_indent (s);
3564
3565   if (n_bytes == 0)
3566     return s;
3567
3568   for (i = 0; i < n_bytes; i++)
3569     {
3570       if (!short_form && (i % 32) == 0)
3571         s = format (s, "%08x: ", i);
3572       s = format (s, "%02x", bytes[i]);
3573       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3574         s = format (s, "\n%U", format_white_space, indent);
3575     }
3576
3577   return s;
3578 }
3579
3580 static void
3581 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3582                                             * mp)
3583 {
3584   vat_main_t *vam = &vat_main;
3585   i32 retval = ntohl (mp->retval);
3586   if (retval == 0)
3587     {
3588       print (vam->ofp, "classify table info :");
3589       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3590              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3591              ntohl (mp->miss_next_index));
3592       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3593              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3594              ntohl (mp->match_n_vectors));
3595       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3596              ntohl (mp->mask_length));
3597     }
3598   vam->retval = retval;
3599   vam->result_ready = 1;
3600 }
3601
3602 static void
3603   vl_api_classify_table_info_reply_t_handler_json
3604   (vl_api_classify_table_info_reply_t * mp)
3605 {
3606   vat_main_t *vam = &vat_main;
3607   vat_json_node_t node;
3608
3609   i32 retval = ntohl (mp->retval);
3610   if (retval == 0)
3611     {
3612       vat_json_init_object (&node);
3613
3614       vat_json_object_add_int (&node, "sessions",
3615                                ntohl (mp->active_sessions));
3616       vat_json_object_add_int (&node, "nexttbl",
3617                                ntohl (mp->next_table_index));
3618       vat_json_object_add_int (&node, "nextnode",
3619                                ntohl (mp->miss_next_index));
3620       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3621       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3622       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3623       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3624                       ntohl (mp->mask_length), 0);
3625       vat_json_object_add_string_copy (&node, "mask", s);
3626
3627       vat_json_print (vam->ofp, &node);
3628       vat_json_free (&node);
3629     }
3630   vam->retval = ntohl (mp->retval);
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3636                                            mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639
3640   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3641          ntohl (mp->hit_next_index), ntohl (mp->advance),
3642          ntohl (mp->opaque_index));
3643   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3644          ntohl (mp->match_length));
3645 }
3646
3647 static void
3648   vl_api_classify_session_details_t_handler_json
3649   (vl_api_classify_session_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   vat_json_node_t *node = NULL;
3653
3654   if (VAT_JSON_ARRAY != vam->json_tree.type)
3655     {
3656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3657       vat_json_init_array (&vam->json_tree);
3658     }
3659   node = vat_json_array_add (&vam->json_tree);
3660
3661   vat_json_init_object (node);
3662   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3663   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3664   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3665   u8 *s =
3666     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3667             0);
3668   vat_json_object_add_string_copy (node, "match", s);
3669 }
3670
3671 static void vl_api_pg_create_interface_reply_t_handler
3672   (vl_api_pg_create_interface_reply_t * mp)
3673 {
3674   vat_main_t *vam = &vat_main;
3675
3676   vam->retval = ntohl (mp->retval);
3677   vam->result_ready = 1;
3678 }
3679
3680 static void vl_api_pg_create_interface_reply_t_handler_json
3681   (vl_api_pg_create_interface_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, "sw_if_index", ntohl (mp->sw_if_index));
3692
3693       vat_json_print (vam->ofp, &node);
3694       vat_json_free (&node);
3695     }
3696   vam->retval = ntohl (mp->retval);
3697   vam->result_ready = 1;
3698 }
3699
3700 static void vl_api_policer_classify_details_t_handler
3701   (vl_api_policer_classify_details_t * mp)
3702 {
3703   vat_main_t *vam = &vat_main;
3704
3705   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3706          ntohl (mp->table_index));
3707 }
3708
3709 static void vl_api_policer_classify_details_t_handler_json
3710   (vl_api_policer_classify_details_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   vat_json_node_t *node;
3714
3715   if (VAT_JSON_ARRAY != vam->json_tree.type)
3716     {
3717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3718       vat_json_init_array (&vam->json_tree);
3719     }
3720   node = vat_json_array_add (&vam->json_tree);
3721
3722   vat_json_init_object (node);
3723   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3724   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3725 }
3726
3727 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3728   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3729 {
3730   vat_main_t *vam = &vat_main;
3731   i32 retval = ntohl (mp->retval);
3732   if (vam->async_mode)
3733     {
3734       vam->async_errors += (retval < 0);
3735     }
3736   else
3737     {
3738       vam->retval = retval;
3739       vam->sw_if_index = ntohl (mp->sw_if_index);
3740       vam->result_ready = 1;
3741     }
3742 }
3743
3744 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3745   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3746 {
3747   vat_main_t *vam = &vat_main;
3748   vat_json_node_t node;
3749
3750   vat_json_init_object (&node);
3751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3753
3754   vat_json_print (vam->ofp, &node);
3755   vat_json_free (&node);
3756
3757   vam->retval = ntohl (mp->retval);
3758   vam->result_ready = 1;
3759 }
3760
3761 static void vl_api_flow_classify_details_t_handler
3762   (vl_api_flow_classify_details_t * mp)
3763 {
3764   vat_main_t *vam = &vat_main;
3765
3766   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3767          ntohl (mp->table_index));
3768 }
3769
3770 static void vl_api_flow_classify_details_t_handler_json
3771   (vl_api_flow_classify_details_t * mp)
3772 {
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t *node;
3775
3776   if (VAT_JSON_ARRAY != vam->json_tree.type)
3777     {
3778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3779       vat_json_init_array (&vam->json_tree);
3780     }
3781   node = vat_json_array_add (&vam->json_tree);
3782
3783   vat_json_init_object (node);
3784   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3785   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3786 }
3787
3788
3789
3790 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3791 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3792 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3793 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3794 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3795 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3796 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3797 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3798 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3799 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3800
3801 /*
3802  * Generate boilerplate reply handlers, which
3803  * dig the return value out of the xxx_reply_t API message,
3804  * stick it into vam->retval, and set vam->result_ready
3805  *
3806  * Could also do this by pointing N message decode slots at
3807  * a single function, but that could break in subtle ways.
3808  */
3809
3810 #define foreach_standard_reply_retval_handler           \
3811 _(sw_interface_set_flags_reply)                         \
3812 _(sw_interface_add_del_address_reply)                   \
3813 _(sw_interface_set_table_reply)                         \
3814 _(sw_interface_set_mpls_enable_reply)                   \
3815 _(sw_interface_set_vpath_reply)                         \
3816 _(sw_interface_set_vxlan_bypass_reply)                  \
3817 _(sw_interface_set_l2_bridge_reply)                     \
3818 _(bridge_domain_add_del_reply)                          \
3819 _(sw_interface_set_l2_xconnect_reply)                   \
3820 _(l2fib_add_del_reply)                                  \
3821 _(ip_add_del_route_reply)                               \
3822 _(ip_mroute_add_del_reply)                              \
3823 _(mpls_route_add_del_reply)                             \
3824 _(mpls_ip_bind_unbind_reply)                            \
3825 _(proxy_arp_add_del_reply)                              \
3826 _(proxy_arp_intfc_enable_disable_reply)                 \
3827 _(sw_interface_set_unnumbered_reply)                    \
3828 _(ip_neighbor_add_del_reply)                            \
3829 _(reset_vrf_reply)                                      \
3830 _(oam_add_del_reply)                                    \
3831 _(reset_fib_reply)                                      \
3832 _(dhcp_proxy_config_reply)                              \
3833 _(dhcp_proxy_set_vss_reply)                             \
3834 _(dhcp_client_config_reply)                             \
3835 _(set_ip_flow_hash_reply)                               \
3836 _(sw_interface_ip6_enable_disable_reply)                \
3837 _(sw_interface_ip6_set_link_local_address_reply)        \
3838 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3839 _(sw_interface_ip6nd_ra_config_reply)                   \
3840 _(set_arp_neighbor_limit_reply)                         \
3841 _(l2_patch_add_del_reply)                               \
3842 _(sr_tunnel_add_del_reply)                              \
3843 _(sr_policy_add_del_reply)                              \
3844 _(sr_multicast_map_add_del_reply)                       \
3845 _(classify_add_del_session_reply)                       \
3846 _(classify_set_interface_ip_table_reply)                \
3847 _(classify_set_interface_l2_tables_reply)               \
3848 _(l2tpv3_set_tunnel_cookies_reply)                      \
3849 _(l2tpv3_interface_enable_disable_reply)                \
3850 _(l2tpv3_set_lookup_key_reply)                          \
3851 _(l2_fib_clear_table_reply)                             \
3852 _(l2_interface_efp_filter_reply)                        \
3853 _(l2_interface_vlan_tag_rewrite_reply)                  \
3854 _(modify_vhost_user_if_reply)                           \
3855 _(delete_vhost_user_if_reply)                           \
3856 _(want_ip4_arp_events_reply)                            \
3857 _(want_ip6_nd_events_reply)                             \
3858 _(input_acl_set_interface_reply)                        \
3859 _(ipsec_spd_add_del_reply)                              \
3860 _(ipsec_interface_add_del_spd_reply)                    \
3861 _(ipsec_spd_add_del_entry_reply)                        \
3862 _(ipsec_sad_add_del_entry_reply)                        \
3863 _(ipsec_sa_set_key_reply)                               \
3864 _(ikev2_profile_add_del_reply)                          \
3865 _(ikev2_profile_set_auth_reply)                         \
3866 _(ikev2_profile_set_id_reply)                           \
3867 _(ikev2_profile_set_ts_reply)                           \
3868 _(ikev2_set_local_key_reply)                            \
3869 _(ikev2_set_responder_reply)                            \
3870 _(ikev2_set_ike_transforms_reply)                       \
3871 _(ikev2_set_esp_transforms_reply)                       \
3872 _(ikev2_set_sa_lifetime_reply)                          \
3873 _(ikev2_initiate_sa_init_reply)                         \
3874 _(ikev2_initiate_del_ike_sa_reply)                      \
3875 _(ikev2_initiate_del_child_sa_reply)                    \
3876 _(ikev2_initiate_rekey_child_sa_reply)                  \
3877 _(delete_loopback_reply)                                \
3878 _(bd_ip_mac_add_del_reply)                              \
3879 _(map_del_domain_reply)                                 \
3880 _(map_add_del_rule_reply)                               \
3881 _(want_interface_events_reply)                          \
3882 _(want_stats_reply)                                     \
3883 _(cop_interface_enable_disable_reply)                   \
3884 _(cop_whitelist_enable_disable_reply)                   \
3885 _(sw_interface_clear_stats_reply)                       \
3886 _(ioam_enable_reply)                              \
3887 _(ioam_disable_reply)                              \
3888 _(one_add_del_locator_reply)                            \
3889 _(one_add_del_local_eid_reply)                          \
3890 _(one_add_del_remote_mapping_reply)                     \
3891 _(one_add_del_adjacency_reply)                          \
3892 _(one_add_del_map_resolver_reply)                       \
3893 _(one_add_del_map_server_reply)                         \
3894 _(one_enable_disable_reply)                             \
3895 _(one_rloc_probe_enable_disable_reply)                  \
3896 _(one_map_register_enable_disable_reply)                \
3897 _(one_pitr_set_locator_set_reply)                       \
3898 _(one_map_request_mode_reply)                           \
3899 _(one_add_del_map_request_itr_rlocs_reply)              \
3900 _(one_eid_table_add_del_map_reply)                      \
3901 _(gpe_add_del_fwd_entry_reply)                          \
3902 _(gpe_enable_disable_reply)                             \
3903 _(gpe_add_del_iface_reply)                              \
3904 _(vxlan_gpe_add_del_tunnel_reply)                       \
3905 _(af_packet_delete_reply)                               \
3906 _(policer_classify_set_interface_reply)                 \
3907 _(netmap_create_reply)                                  \
3908 _(netmap_delete_reply)                                  \
3909 _(set_ipfix_exporter_reply)                             \
3910 _(set_ipfix_classify_stream_reply)                      \
3911 _(ipfix_classify_table_add_del_reply)                   \
3912 _(flow_classify_set_interface_reply)                    \
3913 _(sw_interface_span_enable_disable_reply)               \
3914 _(pg_capture_reply)                                     \
3915 _(pg_enable_disable_reply)                              \
3916 _(ip_source_and_port_range_check_add_del_reply)         \
3917 _(ip_source_and_port_range_check_interface_add_del_reply)\
3918 _(delete_subif_reply)                                   \
3919 _(l2_interface_pbb_tag_rewrite_reply)                   \
3920 _(punt_reply)                                           \
3921 _(feature_enable_disable_reply)                         \
3922 _(sw_interface_tag_add_del_reply)                       \
3923 _(sw_interface_set_mtu_reply)
3924
3925 #if DPDK > 0
3926 #define foreach_standard_dpdk_reply_retval_handler      \
3927 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3928 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3929 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3930 #endif
3931
3932 #define _(n)                                    \
3933     static void vl_api_##n##_t_handler          \
3934     (vl_api_##n##_t * mp)                       \
3935     {                                           \
3936         vat_main_t * vam = &vat_main;           \
3937         i32 retval = ntohl(mp->retval);         \
3938         if (vam->async_mode) {                  \
3939             vam->async_errors += (retval < 0);  \
3940         } else {                                \
3941             vam->retval = retval;               \
3942             vam->result_ready = 1;              \
3943         }                                       \
3944     }
3945 foreach_standard_reply_retval_handler;
3946 #undef _
3947
3948 #define _(n)                                    \
3949     static void vl_api_##n##_t_handler_json     \
3950     (vl_api_##n##_t * mp)                       \
3951     {                                           \
3952         vat_main_t * vam = &vat_main;           \
3953         vat_json_node_t node;                   \
3954         vat_json_init_object(&node);            \
3955         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3956         vat_json_print(vam->ofp, &node);        \
3957         vam->retval = ntohl(mp->retval);        \
3958         vam->result_ready = 1;                  \
3959     }
3960 foreach_standard_reply_retval_handler;
3961 #undef _
3962
3963 #if DPDK > 0
3964 #define _(n)                                    \
3965     static void vl_api_##n##_t_handler          \
3966     (vl_api_##n##_t * mp)                       \
3967     {                                           \
3968         vat_main_t * vam = &vat_main;           \
3969         i32 retval = ntohl(mp->retval);         \
3970         if (vam->async_mode) {                  \
3971             vam->async_errors += (retval < 0);  \
3972         } else {                                \
3973             vam->retval = retval;               \
3974             vam->result_ready = 1;              \
3975         }                                       \
3976     }
3977 foreach_standard_dpdk_reply_retval_handler;
3978 #undef _
3979
3980 #define _(n)                                    \
3981     static void vl_api_##n##_t_handler_json     \
3982     (vl_api_##n##_t * mp)                       \
3983     {                                           \
3984         vat_main_t * vam = &vat_main;           \
3985         vat_json_node_t node;                   \
3986         vat_json_init_object(&node);            \
3987         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3988         vat_json_print(vam->ofp, &node);        \
3989         vam->retval = ntohl(mp->retval);        \
3990         vam->result_ready = 1;                  \
3991     }
3992 foreach_standard_dpdk_reply_retval_handler;
3993 #undef _
3994 #endif
3995
3996 /*
3997  * Table of message reply handlers, must include boilerplate handlers
3998  * we just generated
3999  */
4000
4001 #define foreach_vpe_api_reply_msg                                       \
4002 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4003 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4004 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4005 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4006 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4007 _(CLI_REPLY, cli_reply)                                                 \
4008 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4009 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4010   sw_interface_add_del_address_reply)                                   \
4011 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4012 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4013 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4014 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4015 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4016   sw_interface_set_l2_xconnect_reply)                                   \
4017 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4018   sw_interface_set_l2_bridge_reply)                                     \
4019 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4020 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4021 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4022 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4023 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4024 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4025 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4026 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4027 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4028 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4029 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4030 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4031 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4032 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4033 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4034 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4035   proxy_arp_intfc_enable_disable_reply)                                 \
4036 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4037 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4038   sw_interface_set_unnumbered_reply)                                    \
4039 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4040 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4041 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4042 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4043 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4044 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4045 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4046 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4047 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4048 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4049 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4050 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4051   sw_interface_ip6_enable_disable_reply)                                \
4052 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4053   sw_interface_ip6_set_link_local_address_reply)                        \
4054 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4055   sw_interface_ip6nd_ra_prefix_reply)                                   \
4056 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4057   sw_interface_ip6nd_ra_config_reply)                                   \
4058 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4059 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4060 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4061 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4062 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4063 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4064 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4065 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4066 classify_set_interface_ip_table_reply)                                  \
4067 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4068   classify_set_interface_l2_tables_reply)                               \
4069 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4070 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4071 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4072 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4073 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4074   l2tpv3_interface_enable_disable_reply)                                \
4075 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4076 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4077 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4078 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4079 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4080 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4081 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4082 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4083 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4084 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4085 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4086 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4087 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4088 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4089 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4090 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4091 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4092 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4093 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4094 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4095 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4096 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4097 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4098 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4099 _(IP_DETAILS, ip_details)                                               \
4100 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4101 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4102 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4103 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4104 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4105 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4106 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4107 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4108 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4109 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4110 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4111 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4112 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4113 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4114 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4115 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4116 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4117 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4118 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4119 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4120 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4121 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4122 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4123 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4124 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4125 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4126 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4127 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4128 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4129 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4130 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4131 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4132 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4133 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4134 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4135 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4136 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4137 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4138 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4139 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4140 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4141 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4142 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4143 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4144 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4145 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4146 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4147 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4148 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4149   one_map_register_enable_disable_reply)                                \
4150 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4151   one_rloc_probe_enable_disable_reply)                                  \
4152 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4153 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4154 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4155 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4156 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4157 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4158 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4159 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4160 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4161 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4162 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4163 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4164 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4165 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4166 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4167 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4168   gpe_fwd_entry_path_details)                                           \
4169 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4170 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4171   one_add_del_map_request_itr_rlocs_reply)                              \
4172 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4173   one_get_map_request_itr_rlocs_reply)                                  \
4174 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4175 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4176 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4177 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4178   show_one_map_register_state_reply)                                    \
4179 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4180 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4181 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4182 _(POLICER_DETAILS, policer_details)                                     \
4183 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4184 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4185 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4186 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4187 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4188 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4189 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4190 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4191 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4192 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4193 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4194 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4195 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4196 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4197 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4198 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4199 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4200 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4201 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4202 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4203 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4204 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4205 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4206 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4207 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4208  ip_source_and_port_range_check_add_del_reply)                          \
4209 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4210  ip_source_and_port_range_check_interface_add_del_reply)                \
4211 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4212 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4213 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4214 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4215 _(PUNT_REPLY, punt_reply)                                               \
4216 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4217 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4218 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4219 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4220 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4221 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4222 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4223 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4224
4225 #if DPDK > 0
4226 #define foreach_vpe_dpdk_api_reply_msg                                  \
4227 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4228   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4229 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4230   sw_interface_set_dpdk_hqos_subport_reply)                             \
4231 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4232   sw_interface_set_dpdk_hqos_tctbl_reply)
4233 #endif
4234
4235 typedef struct
4236 {
4237   u8 *name;
4238   u32 value;
4239 } name_sort_t;
4240
4241
4242 #define STR_VTR_OP_CASE(op)     \
4243     case L2_VTR_ ## op:         \
4244         return "" # op;
4245
4246 static const char *
4247 str_vtr_op (u32 vtr_op)
4248 {
4249   switch (vtr_op)
4250     {
4251       STR_VTR_OP_CASE (DISABLED);
4252       STR_VTR_OP_CASE (PUSH_1);
4253       STR_VTR_OP_CASE (PUSH_2);
4254       STR_VTR_OP_CASE (POP_1);
4255       STR_VTR_OP_CASE (POP_2);
4256       STR_VTR_OP_CASE (TRANSLATE_1_1);
4257       STR_VTR_OP_CASE (TRANSLATE_1_2);
4258       STR_VTR_OP_CASE (TRANSLATE_2_1);
4259       STR_VTR_OP_CASE (TRANSLATE_2_2);
4260     }
4261
4262   return "UNKNOWN";
4263 }
4264
4265 static int
4266 dump_sub_interface_table (vat_main_t * vam)
4267 {
4268   const sw_interface_subif_t *sub = NULL;
4269
4270   if (vam->json_output)
4271     {
4272       clib_warning
4273         ("JSON output supported only for VPE API calls and dump_stats_table");
4274       return -99;
4275     }
4276
4277   print (vam->ofp,
4278          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4279          "Interface", "sw_if_index",
4280          "sub id", "dot1ad", "tags", "outer id",
4281          "inner id", "exact", "default", "outer any", "inner any");
4282
4283   vec_foreach (sub, vam->sw_if_subif_table)
4284   {
4285     print (vam->ofp,
4286            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4287            sub->interface_name,
4288            sub->sw_if_index,
4289            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4290            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4291            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4292            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4293     if (sub->vtr_op != L2_VTR_DISABLED)
4294       {
4295         print (vam->ofp,
4296                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4297                "tag1: %d tag2: %d ]",
4298                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4299                sub->vtr_tag1, sub->vtr_tag2);
4300       }
4301   }
4302
4303   return 0;
4304 }
4305
4306 static int
4307 name_sort_cmp (void *a1, void *a2)
4308 {
4309   name_sort_t *n1 = a1;
4310   name_sort_t *n2 = a2;
4311
4312   return strcmp ((char *) n1->name, (char *) n2->name);
4313 }
4314
4315 static int
4316 dump_interface_table (vat_main_t * vam)
4317 {
4318   hash_pair_t *p;
4319   name_sort_t *nses = 0, *ns;
4320
4321   if (vam->json_output)
4322     {
4323       clib_warning
4324         ("JSON output supported only for VPE API calls and dump_stats_table");
4325       return -99;
4326     }
4327
4328   /* *INDENT-OFF* */
4329   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4330   ({
4331     vec_add2 (nses, ns, 1);
4332     ns->name = (u8 *)(p->key);
4333     ns->value = (u32) p->value[0];
4334   }));
4335   /* *INDENT-ON* */
4336
4337   vec_sort_with_function (nses, name_sort_cmp);
4338
4339   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4340   vec_foreach (ns, nses)
4341   {
4342     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4343   }
4344   vec_free (nses);
4345   return 0;
4346 }
4347
4348 static int
4349 dump_ip_table (vat_main_t * vam, int is_ipv6)
4350 {
4351   const ip_details_t *det = NULL;
4352   const ip_address_details_t *address = NULL;
4353   u32 i = ~0;
4354
4355   print (vam->ofp, "%-12s", "sw_if_index");
4356
4357   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4358   {
4359     i++;
4360     if (!det->present)
4361       {
4362         continue;
4363       }
4364     print (vam->ofp, "%-12d", i);
4365     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4366     if (!det->addr)
4367       {
4368         continue;
4369       }
4370     vec_foreach (address, det->addr)
4371     {
4372       print (vam->ofp,
4373              "            %-30U%-13d",
4374              is_ipv6 ? format_ip6_address : format_ip4_address,
4375              address->ip, address->prefix_length);
4376     }
4377   }
4378
4379   return 0;
4380 }
4381
4382 static int
4383 dump_ipv4_table (vat_main_t * vam)
4384 {
4385   if (vam->json_output)
4386     {
4387       clib_warning
4388         ("JSON output supported only for VPE API calls and dump_stats_table");
4389       return -99;
4390     }
4391
4392   return dump_ip_table (vam, 0);
4393 }
4394
4395 static int
4396 dump_ipv6_table (vat_main_t * vam)
4397 {
4398   if (vam->json_output)
4399     {
4400       clib_warning
4401         ("JSON output supported only for VPE API calls and dump_stats_table");
4402       return -99;
4403     }
4404
4405   return dump_ip_table (vam, 1);
4406 }
4407
4408 static char *
4409 counter_type_to_str (u8 counter_type, u8 is_combined)
4410 {
4411   if (!is_combined)
4412     {
4413       switch (counter_type)
4414         {
4415         case VNET_INTERFACE_COUNTER_DROP:
4416           return "drop";
4417         case VNET_INTERFACE_COUNTER_PUNT:
4418           return "punt";
4419         case VNET_INTERFACE_COUNTER_IP4:
4420           return "ip4";
4421         case VNET_INTERFACE_COUNTER_IP6:
4422           return "ip6";
4423         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4424           return "rx-no-buf";
4425         case VNET_INTERFACE_COUNTER_RX_MISS:
4426           return "rx-miss";
4427         case VNET_INTERFACE_COUNTER_RX_ERROR:
4428           return "rx-error";
4429         case VNET_INTERFACE_COUNTER_TX_ERROR:
4430           return "tx-error";
4431         default:
4432           return "INVALID-COUNTER-TYPE";
4433         }
4434     }
4435   else
4436     {
4437       switch (counter_type)
4438         {
4439         case VNET_INTERFACE_COUNTER_RX:
4440           return "rx";
4441         case VNET_INTERFACE_COUNTER_TX:
4442           return "tx";
4443         default:
4444           return "INVALID-COUNTER-TYPE";
4445         }
4446     }
4447 }
4448
4449 static int
4450 dump_stats_table (vat_main_t * vam)
4451 {
4452   vat_json_node_t node;
4453   vat_json_node_t *msg_array;
4454   vat_json_node_t *msg;
4455   vat_json_node_t *counter_array;
4456   vat_json_node_t *counter;
4457   interface_counter_t c;
4458   u64 packets;
4459   ip4_fib_counter_t *c4;
4460   ip6_fib_counter_t *c6;
4461   ip4_nbr_counter_t *n4;
4462   ip6_nbr_counter_t *n6;
4463   int i, j;
4464
4465   if (!vam->json_output)
4466     {
4467       clib_warning ("dump_stats_table supported only in JSON format");
4468       return -99;
4469     }
4470
4471   vat_json_init_object (&node);
4472
4473   /* interface counters */
4474   msg_array = vat_json_object_add (&node, "interface_counters");
4475   vat_json_init_array (msg_array);
4476   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4477     {
4478       msg = vat_json_array_add (msg_array);
4479       vat_json_init_object (msg);
4480       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4481                                        (u8 *) counter_type_to_str (i, 0));
4482       vat_json_object_add_int (msg, "is_combined", 0);
4483       counter_array = vat_json_object_add (msg, "data");
4484       vat_json_init_array (counter_array);
4485       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4486         {
4487           packets = vam->simple_interface_counters[i][j];
4488           vat_json_array_add_uint (counter_array, packets);
4489         }
4490     }
4491   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4492     {
4493       msg = vat_json_array_add (msg_array);
4494       vat_json_init_object (msg);
4495       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4496                                        (u8 *) counter_type_to_str (i, 1));
4497       vat_json_object_add_int (msg, "is_combined", 1);
4498       counter_array = vat_json_object_add (msg, "data");
4499       vat_json_init_array (counter_array);
4500       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4501         {
4502           c = vam->combined_interface_counters[i][j];
4503           counter = vat_json_array_add (counter_array);
4504           vat_json_init_object (counter);
4505           vat_json_object_add_uint (counter, "packets", c.packets);
4506           vat_json_object_add_uint (counter, "bytes", c.bytes);
4507         }
4508     }
4509
4510   /* ip4 fib counters */
4511   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4512   vat_json_init_array (msg_array);
4513   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4514     {
4515       msg = vat_json_array_add (msg_array);
4516       vat_json_init_object (msg);
4517       vat_json_object_add_uint (msg, "vrf_id",
4518                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4519       counter_array = vat_json_object_add (msg, "c");
4520       vat_json_init_array (counter_array);
4521       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4522         {
4523           counter = vat_json_array_add (counter_array);
4524           vat_json_init_object (counter);
4525           c4 = &vam->ip4_fib_counters[i][j];
4526           vat_json_object_add_ip4 (counter, "address", c4->address);
4527           vat_json_object_add_uint (counter, "address_length",
4528                                     c4->address_length);
4529           vat_json_object_add_uint (counter, "packets", c4->packets);
4530           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4531         }
4532     }
4533
4534   /* ip6 fib counters */
4535   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4536   vat_json_init_array (msg_array);
4537   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4538     {
4539       msg = vat_json_array_add (msg_array);
4540       vat_json_init_object (msg);
4541       vat_json_object_add_uint (msg, "vrf_id",
4542                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4543       counter_array = vat_json_object_add (msg, "c");
4544       vat_json_init_array (counter_array);
4545       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4546         {
4547           counter = vat_json_array_add (counter_array);
4548           vat_json_init_object (counter);
4549           c6 = &vam->ip6_fib_counters[i][j];
4550           vat_json_object_add_ip6 (counter, "address", c6->address);
4551           vat_json_object_add_uint (counter, "address_length",
4552                                     c6->address_length);
4553           vat_json_object_add_uint (counter, "packets", c6->packets);
4554           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4555         }
4556     }
4557
4558   /* ip4 nbr counters */
4559   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4560   vat_json_init_array (msg_array);
4561   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4562     {
4563       msg = vat_json_array_add (msg_array);
4564       vat_json_init_object (msg);
4565       vat_json_object_add_uint (msg, "sw_if_index", i);
4566       counter_array = vat_json_object_add (msg, "c");
4567       vat_json_init_array (counter_array);
4568       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4569         {
4570           counter = vat_json_array_add (counter_array);
4571           vat_json_init_object (counter);
4572           n4 = &vam->ip4_nbr_counters[i][j];
4573           vat_json_object_add_ip4 (counter, "address", n4->address);
4574           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4575           vat_json_object_add_uint (counter, "packets", n4->packets);
4576           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4577         }
4578     }
4579
4580   /* ip6 nbr counters */
4581   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4582   vat_json_init_array (msg_array);
4583   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4584     {
4585       msg = vat_json_array_add (msg_array);
4586       vat_json_init_object (msg);
4587       vat_json_object_add_uint (msg, "sw_if_index", i);
4588       counter_array = vat_json_object_add (msg, "c");
4589       vat_json_init_array (counter_array);
4590       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4591         {
4592           counter = vat_json_array_add (counter_array);
4593           vat_json_init_object (counter);
4594           n6 = &vam->ip6_nbr_counters[i][j];
4595           vat_json_object_add_ip6 (counter, "address", n6->address);
4596           vat_json_object_add_uint (counter, "packets", n6->packets);
4597           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4598         }
4599     }
4600
4601   vat_json_print (vam->ofp, &node);
4602   vat_json_free (&node);
4603
4604   return 0;
4605 }
4606
4607 int
4608 exec (vat_main_t * vam)
4609 {
4610   api_main_t *am = &api_main;
4611   vl_api_cli_request_t *mp;
4612   f64 timeout;
4613   void *oldheap;
4614   u8 *cmd = 0;
4615   unformat_input_t *i = vam->input;
4616
4617   if (vec_len (i->buffer) == 0)
4618     return -1;
4619
4620   if (vam->exec_mode == 0 && unformat (i, "mode"))
4621     {
4622       vam->exec_mode = 1;
4623       return 0;
4624     }
4625   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4626     {
4627       vam->exec_mode = 0;
4628       return 0;
4629     }
4630
4631
4632   M (CLI_REQUEST, mp);
4633
4634   /*
4635    * Copy cmd into shared memory.
4636    * In order for the CLI command to work, it
4637    * must be a vector ending in \n, not a C-string ending
4638    * in \n\0.
4639    */
4640   pthread_mutex_lock (&am->vlib_rp->mutex);
4641   oldheap = svm_push_data_heap (am->vlib_rp);
4642
4643   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4644   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4645
4646   svm_pop_heap (oldheap);
4647   pthread_mutex_unlock (&am->vlib_rp->mutex);
4648
4649   mp->cmd_in_shmem = (u64) cmd;
4650   S (mp);
4651   timeout = vat_time_now (vam) + 10.0;
4652
4653   while (vat_time_now (vam) < timeout)
4654     {
4655       if (vam->result_ready == 1)
4656         {
4657           u8 *free_me;
4658           if (vam->shmem_result != NULL)
4659             print (vam->ofp, "%s", vam->shmem_result);
4660           pthread_mutex_lock (&am->vlib_rp->mutex);
4661           oldheap = svm_push_data_heap (am->vlib_rp);
4662
4663           free_me = (u8 *) vam->shmem_result;
4664           vec_free (free_me);
4665
4666           svm_pop_heap (oldheap);
4667           pthread_mutex_unlock (&am->vlib_rp->mutex);
4668           return 0;
4669         }
4670     }
4671   return -99;
4672 }
4673
4674 /*
4675  * Future replacement of exec() that passes CLI buffers directly in
4676  * the API messages instead of an additional shared memory area.
4677  */
4678 static int
4679 exec_inband (vat_main_t * vam)
4680 {
4681   vl_api_cli_inband_t *mp;
4682   unformat_input_t *i = vam->input;
4683   int ret;
4684
4685   if (vec_len (i->buffer) == 0)
4686     return -1;
4687
4688   if (vam->exec_mode == 0 && unformat (i, "mode"))
4689     {
4690       vam->exec_mode = 1;
4691       return 0;
4692     }
4693   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4694     {
4695       vam->exec_mode = 0;
4696       return 0;
4697     }
4698
4699   /*
4700    * In order for the CLI command to work, it
4701    * must be a vector ending in \n, not a C-string ending
4702    * in \n\0.
4703    */
4704   u32 len = vec_len (vam->input->buffer);
4705   M2 (CLI_INBAND, mp, len);
4706   clib_memcpy (mp->cmd, vam->input->buffer, len);
4707   mp->length = htonl (len);
4708
4709   S (mp);
4710   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4711   return ret;
4712 }
4713
4714 static int
4715 api_create_loopback (vat_main_t * vam)
4716 {
4717   unformat_input_t *i = vam->input;
4718   vl_api_create_loopback_t *mp;
4719   u8 mac_address[6];
4720   u8 mac_set = 0;
4721   int ret;
4722
4723   memset (mac_address, 0, sizeof (mac_address));
4724
4725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4726     {
4727       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4728         mac_set = 1;
4729       else
4730         break;
4731     }
4732
4733   /* Construct the API message */
4734   M (CREATE_LOOPBACK, mp);
4735   if (mac_set)
4736     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4737
4738   S (mp);
4739   W (ret);
4740   return ret;
4741 }
4742
4743 static int
4744 api_delete_loopback (vat_main_t * vam)
4745 {
4746   unformat_input_t *i = vam->input;
4747   vl_api_delete_loopback_t *mp;
4748   u32 sw_if_index = ~0;
4749   int ret;
4750
4751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4752     {
4753       if (unformat (i, "sw_if_index %d", &sw_if_index))
4754         ;
4755       else
4756         break;
4757     }
4758
4759   if (sw_if_index == ~0)
4760     {
4761       errmsg ("missing sw_if_index");
4762       return -99;
4763     }
4764
4765   /* Construct the API message */
4766   M (DELETE_LOOPBACK, mp);
4767   mp->sw_if_index = ntohl (sw_if_index);
4768
4769   S (mp);
4770   W (ret);
4771   return ret;
4772 }
4773
4774 static int
4775 api_want_stats (vat_main_t * vam)
4776 {
4777   unformat_input_t *i = vam->input;
4778   vl_api_want_stats_t *mp;
4779   int enable = -1;
4780   int ret;
4781
4782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4783     {
4784       if (unformat (i, "enable"))
4785         enable = 1;
4786       else if (unformat (i, "disable"))
4787         enable = 0;
4788       else
4789         break;
4790     }
4791
4792   if (enable == -1)
4793     {
4794       errmsg ("missing enable|disable");
4795       return -99;
4796     }
4797
4798   M (WANT_STATS, mp);
4799   mp->enable_disable = enable;
4800
4801   S (mp);
4802   W (ret);
4803   return ret;
4804 }
4805
4806 static int
4807 api_want_interface_events (vat_main_t * vam)
4808 {
4809   unformat_input_t *i = vam->input;
4810   vl_api_want_interface_events_t *mp;
4811   int enable = -1;
4812   int ret;
4813
4814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4815     {
4816       if (unformat (i, "enable"))
4817         enable = 1;
4818       else if (unformat (i, "disable"))
4819         enable = 0;
4820       else
4821         break;
4822     }
4823
4824   if (enable == -1)
4825     {
4826       errmsg ("missing enable|disable");
4827       return -99;
4828     }
4829
4830   M (WANT_INTERFACE_EVENTS, mp);
4831   mp->enable_disable = enable;
4832
4833   vam->interface_event_display = enable;
4834
4835   S (mp);
4836   W (ret);
4837   return ret;
4838 }
4839
4840
4841 /* Note: non-static, called once to set up the initial intfc table */
4842 int
4843 api_sw_interface_dump (vat_main_t * vam)
4844 {
4845   vl_api_sw_interface_dump_t *mp;
4846   vl_api_control_ping_t *mp_ping;
4847   hash_pair_t *p;
4848   name_sort_t *nses = 0, *ns;
4849   sw_interface_subif_t *sub = NULL;
4850   int ret;
4851
4852   /* Toss the old name table */
4853   /* *INDENT-OFF* */
4854   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4855   ({
4856     vec_add2 (nses, ns, 1);
4857     ns->name = (u8 *)(p->key);
4858     ns->value = (u32) p->value[0];
4859   }));
4860   /* *INDENT-ON* */
4861
4862   hash_free (vam->sw_if_index_by_interface_name);
4863
4864   vec_foreach (ns, nses) vec_free (ns->name);
4865
4866   vec_free (nses);
4867
4868   vec_foreach (sub, vam->sw_if_subif_table)
4869   {
4870     vec_free (sub->interface_name);
4871   }
4872   vec_free (vam->sw_if_subif_table);
4873
4874   /* recreate the interface name hash table */
4875   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4876
4877   /* Get list of ethernets */
4878   M (SW_INTERFACE_DUMP, mp);
4879   mp->name_filter_valid = 1;
4880   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4881   S (mp);
4882
4883   /* and local / loopback interfaces */
4884   M (SW_INTERFACE_DUMP, mp);
4885   mp->name_filter_valid = 1;
4886   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4887   S (mp);
4888
4889   /* and packet-generator interfaces */
4890   M (SW_INTERFACE_DUMP, mp);
4891   mp->name_filter_valid = 1;
4892   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4893   S (mp);
4894
4895   /* and vxlan-gpe tunnel interfaces */
4896   M (SW_INTERFACE_DUMP, mp);
4897   mp->name_filter_valid = 1;
4898   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4899            sizeof (mp->name_filter) - 1);
4900   S (mp);
4901
4902   /* and vxlan tunnel interfaces */
4903   M (SW_INTERFACE_DUMP, mp);
4904   mp->name_filter_valid = 1;
4905   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4906   S (mp);
4907
4908   /* and host (af_packet) interfaces */
4909   M (SW_INTERFACE_DUMP, mp);
4910   mp->name_filter_valid = 1;
4911   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4912   S (mp);
4913
4914   /* and l2tpv3 tunnel interfaces */
4915   M (SW_INTERFACE_DUMP, mp);
4916   mp->name_filter_valid = 1;
4917   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4918            sizeof (mp->name_filter) - 1);
4919   S (mp);
4920
4921   /* and GRE tunnel interfaces */
4922   M (SW_INTERFACE_DUMP, mp);
4923   mp->name_filter_valid = 1;
4924   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4925   S (mp);
4926
4927   /* and LISP-GPE interfaces */
4928   M (SW_INTERFACE_DUMP, mp);
4929   mp->name_filter_valid = 1;
4930   strncpy ((char *) mp->name_filter, "lisp_gpe",
4931            sizeof (mp->name_filter) - 1);
4932   S (mp);
4933
4934   /* and IPSEC tunnel interfaces */
4935   M (SW_INTERFACE_DUMP, mp);
4936   mp->name_filter_valid = 1;
4937   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4938   S (mp);
4939
4940   /* Use a control ping for synchronization */
4941   M (CONTROL_PING, mp_ping);
4942   S (mp_ping);
4943
4944   W (ret);
4945   return ret;
4946 }
4947
4948 static int
4949 api_sw_interface_set_flags (vat_main_t * vam)
4950 {
4951   unformat_input_t *i = vam->input;
4952   vl_api_sw_interface_set_flags_t *mp;
4953   u32 sw_if_index;
4954   u8 sw_if_index_set = 0;
4955   u8 admin_up = 0, link_up = 0;
4956   int ret;
4957
4958   /* Parse args required to build the message */
4959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4960     {
4961       if (unformat (i, "admin-up"))
4962         admin_up = 1;
4963       else if (unformat (i, "admin-down"))
4964         admin_up = 0;
4965       else if (unformat (i, "link-up"))
4966         link_up = 1;
4967       else if (unformat (i, "link-down"))
4968         link_up = 0;
4969       else
4970         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4971         sw_if_index_set = 1;
4972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4973         sw_if_index_set = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_FLAGS, mp);
4986   mp->sw_if_index = ntohl (sw_if_index);
4987   mp->admin_up_down = admin_up;
4988   mp->link_up_down = link_up;
4989
4990   /* send it... */
4991   S (mp);
4992
4993   /* Wait for a reply, return the good/bad news... */
4994   W (ret);
4995   return ret;
4996 }
4997
4998 static int
4999 api_sw_interface_clear_stats (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_clear_stats_t *mp;
5003   u32 sw_if_index;
5004   u8 sw_if_index_set = 0;
5005   int ret;
5006
5007   /* Parse args required to build the message */
5008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5009     {
5010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5011         sw_if_index_set = 1;
5012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5013         sw_if_index_set = 1;
5014       else
5015         break;
5016     }
5017
5018   /* Construct the API message */
5019   M (SW_INTERFACE_CLEAR_STATS, mp);
5020
5021   if (sw_if_index_set == 1)
5022     mp->sw_if_index = ntohl (sw_if_index);
5023   else
5024     mp->sw_if_index = ~0;
5025
5026   /* send it... */
5027   S (mp);
5028
5029   /* Wait for a reply, return the good/bad news... */
5030   W (ret);
5031   return ret;
5032 }
5033
5034 #if DPDK >0
5035 static int
5036 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5037 {
5038   unformat_input_t *i = vam->input;
5039   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5040   u32 sw_if_index;
5041   u8 sw_if_index_set = 0;
5042   u32 subport;
5043   u8 subport_set = 0;
5044   u32 pipe;
5045   u8 pipe_set = 0;
5046   u32 profile;
5047   u8 profile_set = 0;
5048   int ret;
5049
5050   /* Parse args required to build the message */
5051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5052     {
5053       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5054         sw_if_index_set = 1;
5055       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5056         sw_if_index_set = 1;
5057       else if (unformat (i, "subport %u", &subport))
5058         subport_set = 1;
5059       else
5060         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5061         sw_if_index_set = 1;
5062       else if (unformat (i, "pipe %u", &pipe))
5063         pipe_set = 1;
5064       else if (unformat (i, "profile %u", &profile))
5065         profile_set = 1;
5066       else
5067         break;
5068     }
5069
5070   if (sw_if_index_set == 0)
5071     {
5072       errmsg ("missing interface name or sw_if_index");
5073       return -99;
5074     }
5075
5076   if (subport_set == 0)
5077     {
5078       errmsg ("missing subport ");
5079       return -99;
5080     }
5081
5082   if (pipe_set == 0)
5083     {
5084       errmsg ("missing pipe");
5085       return -99;
5086     }
5087
5088   if (profile_set == 0)
5089     {
5090       errmsg ("missing profile");
5091       return -99;
5092     }
5093
5094   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5095
5096   mp->sw_if_index = ntohl (sw_if_index);
5097   mp->subport = ntohl (subport);
5098   mp->pipe = ntohl (pipe);
5099   mp->profile = ntohl (profile);
5100
5101
5102   S (mp);
5103   W (ret);
5104   return ret;
5105 }
5106
5107 static int
5108 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5109 {
5110   unformat_input_t *i = vam->input;
5111   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5112   u32 sw_if_index;
5113   u8 sw_if_index_set = 0;
5114   u32 subport;
5115   u8 subport_set = 0;
5116   u32 tb_rate = 1250000000;     /* 10GbE */
5117   u32 tb_size = 1000000;
5118   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5119   u32 tc_period = 10;
5120   int ret;
5121
5122   /* Parse args required to build the message */
5123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124     {
5125       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5126         sw_if_index_set = 1;
5127       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "subport %u", &subport))
5130         subport_set = 1;
5131       else
5132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5133         sw_if_index_set = 1;
5134       else if (unformat (i, "rate %u", &tb_rate))
5135         {
5136           u32 tc_id;
5137
5138           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5139                tc_id++)
5140             tc_rate[tc_id] = tb_rate;
5141         }
5142       else if (unformat (i, "bktsize %u", &tb_size))
5143         ;
5144       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5145         ;
5146       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5147         ;
5148       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5149         ;
5150       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5151         ;
5152       else if (unformat (i, "period %u", &tc_period))
5153         ;
5154       else
5155         break;
5156     }
5157
5158   if (sw_if_index_set == 0)
5159     {
5160       errmsg ("missing interface name or sw_if_index");
5161       return -99;
5162     }
5163
5164   if (subport_set == 0)
5165     {
5166       errmsg ("missing subport ");
5167       return -99;
5168     }
5169
5170   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5171
5172   mp->sw_if_index = ntohl (sw_if_index);
5173   mp->subport = ntohl (subport);
5174   mp->tb_rate = ntohl (tb_rate);
5175   mp->tb_size = ntohl (tb_size);
5176   mp->tc_rate[0] = ntohl (tc_rate[0]);
5177   mp->tc_rate[1] = ntohl (tc_rate[1]);
5178   mp->tc_rate[2] = ntohl (tc_rate[2]);
5179   mp->tc_rate[3] = ntohl (tc_rate[3]);
5180   mp->tc_period = ntohl (tc_period);
5181
5182   S (mp);
5183   W (ret);
5184   return ret;
5185 }
5186
5187 static int
5188 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5189 {
5190   unformat_input_t *i = vam->input;
5191   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5192   u32 sw_if_index;
5193   u8 sw_if_index_set = 0;
5194   u8 entry_set = 0;
5195   u8 tc_set = 0;
5196   u8 queue_set = 0;
5197   u32 entry, tc, queue;
5198   int ret;
5199
5200   /* Parse args required to build the message */
5201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5202     {
5203       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5204         sw_if_index_set = 1;
5205       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5206         sw_if_index_set = 1;
5207       else if (unformat (i, "entry %d", &entry))
5208         entry_set = 1;
5209       else if (unformat (i, "tc %d", &tc))
5210         tc_set = 1;
5211       else if (unformat (i, "queue %d", &queue))
5212         queue_set = 1;
5213       else
5214         break;
5215     }
5216
5217   if (sw_if_index_set == 0)
5218     {
5219       errmsg ("missing interface name or sw_if_index");
5220       return -99;
5221     }
5222
5223   if (entry_set == 0)
5224     {
5225       errmsg ("missing entry ");
5226       return -99;
5227     }
5228
5229   if (tc_set == 0)
5230     {
5231       errmsg ("missing traffic class ");
5232       return -99;
5233     }
5234
5235   if (queue_set == 0)
5236     {
5237       errmsg ("missing queue ");
5238       return -99;
5239     }
5240
5241   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5242
5243   mp->sw_if_index = ntohl (sw_if_index);
5244   mp->entry = ntohl (entry);
5245   mp->tc = ntohl (tc);
5246   mp->queue = ntohl (queue);
5247
5248   S (mp);
5249   W (ret);
5250   return ret;
5251 }
5252 #endif
5253
5254 static int
5255 api_sw_interface_add_del_address (vat_main_t * vam)
5256 {
5257   unformat_input_t *i = vam->input;
5258   vl_api_sw_interface_add_del_address_t *mp;
5259   u32 sw_if_index;
5260   u8 sw_if_index_set = 0;
5261   u8 is_add = 1, del_all = 0;
5262   u32 address_length = 0;
5263   u8 v4_address_set = 0;
5264   u8 v6_address_set = 0;
5265   ip4_address_t v4address;
5266   ip6_address_t v6address;
5267   int ret;
5268
5269   /* Parse args required to build the message */
5270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5271     {
5272       if (unformat (i, "del-all"))
5273         del_all = 1;
5274       else if (unformat (i, "del"))
5275         is_add = 0;
5276       else
5277         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5278         sw_if_index_set = 1;
5279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5280         sw_if_index_set = 1;
5281       else if (unformat (i, "%U/%d",
5282                          unformat_ip4_address, &v4address, &address_length))
5283         v4_address_set = 1;
5284       else if (unformat (i, "%U/%d",
5285                          unformat_ip6_address, &v6address, &address_length))
5286         v6_address_set = 1;
5287       else
5288         break;
5289     }
5290
5291   if (sw_if_index_set == 0)
5292     {
5293       errmsg ("missing interface name or sw_if_index");
5294       return -99;
5295     }
5296   if (v4_address_set && v6_address_set)
5297     {
5298       errmsg ("both v4 and v6 addresses set");
5299       return -99;
5300     }
5301   if (!v4_address_set && !v6_address_set && !del_all)
5302     {
5303       errmsg ("no addresses set");
5304       return -99;
5305     }
5306
5307   /* Construct the API message */
5308   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5309
5310   mp->sw_if_index = ntohl (sw_if_index);
5311   mp->is_add = is_add;
5312   mp->del_all = del_all;
5313   if (v6_address_set)
5314     {
5315       mp->is_ipv6 = 1;
5316       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5317     }
5318   else
5319     {
5320       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5321     }
5322   mp->address_length = address_length;
5323
5324   /* send it... */
5325   S (mp);
5326
5327   /* Wait for a reply, return good/bad news  */
5328   W (ret);
5329   return ret;
5330 }
5331
5332 static int
5333 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5334 {
5335   unformat_input_t *i = vam->input;
5336   vl_api_sw_interface_set_mpls_enable_t *mp;
5337   u32 sw_if_index;
5338   u8 sw_if_index_set = 0;
5339   u8 enable = 1;
5340   int ret;
5341
5342   /* Parse args required to build the message */
5343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5344     {
5345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5346         sw_if_index_set = 1;
5347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5348         sw_if_index_set = 1;
5349       else if (unformat (i, "disable"))
5350         enable = 0;
5351       else if (unformat (i, "dis"))
5352         enable = 0;
5353       else
5354         break;
5355     }
5356
5357   if (sw_if_index_set == 0)
5358     {
5359       errmsg ("missing interface name or sw_if_index");
5360       return -99;
5361     }
5362
5363   /* Construct the API message */
5364   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5365
5366   mp->sw_if_index = ntohl (sw_if_index);
5367   mp->enable = enable;
5368
5369   /* send it... */
5370   S (mp);
5371
5372   /* Wait for a reply... */
5373   W (ret);
5374   return ret;
5375 }
5376
5377 static int
5378 api_sw_interface_set_table (vat_main_t * vam)
5379 {
5380   unformat_input_t *i = vam->input;
5381   vl_api_sw_interface_set_table_t *mp;
5382   u32 sw_if_index, vrf_id = 0;
5383   u8 sw_if_index_set = 0;
5384   u8 is_ipv6 = 0;
5385   int ret;
5386
5387   /* Parse args required to build the message */
5388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5389     {
5390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5391         sw_if_index_set = 1;
5392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5393         sw_if_index_set = 1;
5394       else if (unformat (i, "vrf %d", &vrf_id))
5395         ;
5396       else if (unformat (i, "ipv6"))
5397         is_ipv6 = 1;
5398       else
5399         break;
5400     }
5401
5402   if (sw_if_index_set == 0)
5403     {
5404       errmsg ("missing interface name or sw_if_index");
5405       return -99;
5406     }
5407
5408   /* Construct the API message */
5409   M (SW_INTERFACE_SET_TABLE, mp);
5410
5411   mp->sw_if_index = ntohl (sw_if_index);
5412   mp->is_ipv6 = is_ipv6;
5413   mp->vrf_id = ntohl (vrf_id);
5414
5415   /* send it... */
5416   S (mp);
5417
5418   /* Wait for a reply... */
5419   W (ret);
5420   return ret;
5421 }
5422
5423 static void vl_api_sw_interface_get_table_reply_t_handler
5424   (vl_api_sw_interface_get_table_reply_t * mp)
5425 {
5426   vat_main_t *vam = &vat_main;
5427
5428   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5429
5430   vam->retval = ntohl (mp->retval);
5431   vam->result_ready = 1;
5432
5433 }
5434
5435 static void vl_api_sw_interface_get_table_reply_t_handler_json
5436   (vl_api_sw_interface_get_table_reply_t * mp)
5437 {
5438   vat_main_t *vam = &vat_main;
5439   vat_json_node_t node;
5440
5441   vat_json_init_object (&node);
5442   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5443   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5444
5445   vat_json_print (vam->ofp, &node);
5446   vat_json_free (&node);
5447
5448   vam->retval = ntohl (mp->retval);
5449   vam->result_ready = 1;
5450 }
5451
5452 static int
5453 api_sw_interface_get_table (vat_main_t * vam)
5454 {
5455   unformat_input_t *i = vam->input;
5456   vl_api_sw_interface_get_table_t *mp;
5457   u32 sw_if_index;
5458   u8 sw_if_index_set = 0;
5459   u8 is_ipv6 = 0;
5460   int ret;
5461
5462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5463     {
5464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5465         sw_if_index_set = 1;
5466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5467         sw_if_index_set = 1;
5468       else if (unformat (i, "ipv6"))
5469         is_ipv6 = 1;
5470       else
5471         break;
5472     }
5473
5474   if (sw_if_index_set == 0)
5475     {
5476       errmsg ("missing interface name or sw_if_index");
5477       return -99;
5478     }
5479
5480   M (SW_INTERFACE_GET_TABLE, mp);
5481   mp->sw_if_index = htonl (sw_if_index);
5482   mp->is_ipv6 = is_ipv6;
5483
5484   S (mp);
5485   W (ret);
5486   return ret;
5487 }
5488
5489 static int
5490 api_sw_interface_set_vpath (vat_main_t * vam)
5491 {
5492   unformat_input_t *i = vam->input;
5493   vl_api_sw_interface_set_vpath_t *mp;
5494   u32 sw_if_index = 0;
5495   u8 sw_if_index_set = 0;
5496   u8 is_enable = 0;
5497   int ret;
5498
5499   /* Parse args required to build the message */
5500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5501     {
5502       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5503         sw_if_index_set = 1;
5504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5505         sw_if_index_set = 1;
5506       else if (unformat (i, "enable"))
5507         is_enable = 1;
5508       else if (unformat (i, "disable"))
5509         is_enable = 0;
5510       else
5511         break;
5512     }
5513
5514   if (sw_if_index_set == 0)
5515     {
5516       errmsg ("missing interface name or sw_if_index");
5517       return -99;
5518     }
5519
5520   /* Construct the API message */
5521   M (SW_INTERFACE_SET_VPATH, mp);
5522
5523   mp->sw_if_index = ntohl (sw_if_index);
5524   mp->enable = is_enable;
5525
5526   /* send it... */
5527   S (mp);
5528
5529   /* Wait for a reply... */
5530   W (ret);
5531   return ret;
5532 }
5533
5534 static int
5535 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5536 {
5537   unformat_input_t *i = vam->input;
5538   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5539   u32 sw_if_index = 0;
5540   u8 sw_if_index_set = 0;
5541   u8 is_enable = 1;
5542   u8 is_ipv6 = 0;
5543   int ret;
5544
5545   /* Parse args required to build the message */
5546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5547     {
5548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5549         sw_if_index_set = 1;
5550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5551         sw_if_index_set = 1;
5552       else if (unformat (i, "enable"))
5553         is_enable = 1;
5554       else if (unformat (i, "disable"))
5555         is_enable = 0;
5556       else if (unformat (i, "ip4"))
5557         is_ipv6 = 0;
5558       else if (unformat (i, "ip6"))
5559         is_ipv6 = 1;
5560       else
5561         break;
5562     }
5563
5564   if (sw_if_index_set == 0)
5565     {
5566       errmsg ("missing interface name or sw_if_index");
5567       return -99;
5568     }
5569
5570   /* Construct the API message */
5571   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5572
5573   mp->sw_if_index = ntohl (sw_if_index);
5574   mp->enable = is_enable;
5575   mp->is_ipv6 = is_ipv6;
5576
5577   /* send it... */
5578   S (mp);
5579
5580   /* Wait for a reply... */
5581   W (ret);
5582   return ret;
5583 }
5584
5585 static int
5586 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_sw_interface_set_l2_xconnect_t *mp;
5590   u32 rx_sw_if_index;
5591   u8 rx_sw_if_index_set = 0;
5592   u32 tx_sw_if_index;
5593   u8 tx_sw_if_index_set = 0;
5594   u8 enable = 1;
5595   int ret;
5596
5597   /* Parse args required to build the message */
5598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5599     {
5600       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5601         rx_sw_if_index_set = 1;
5602       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5603         tx_sw_if_index_set = 1;
5604       else if (unformat (i, "rx"))
5605         {
5606           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607             {
5608               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5609                             &rx_sw_if_index))
5610                 rx_sw_if_index_set = 1;
5611             }
5612           else
5613             break;
5614         }
5615       else if (unformat (i, "tx"))
5616         {
5617           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5618             {
5619               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5620                             &tx_sw_if_index))
5621                 tx_sw_if_index_set = 1;
5622             }
5623           else
5624             break;
5625         }
5626       else if (unformat (i, "enable"))
5627         enable = 1;
5628       else if (unformat (i, "disable"))
5629         enable = 0;
5630       else
5631         break;
5632     }
5633
5634   if (rx_sw_if_index_set == 0)
5635     {
5636       errmsg ("missing rx interface name or rx_sw_if_index");
5637       return -99;
5638     }
5639
5640   if (enable && (tx_sw_if_index_set == 0))
5641     {
5642       errmsg ("missing tx interface name or tx_sw_if_index");
5643       return -99;
5644     }
5645
5646   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5647
5648   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5649   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5650   mp->enable = enable;
5651
5652   S (mp);
5653   W (ret);
5654   return ret;
5655 }
5656
5657 static int
5658 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5659 {
5660   unformat_input_t *i = vam->input;
5661   vl_api_sw_interface_set_l2_bridge_t *mp;
5662   u32 rx_sw_if_index;
5663   u8 rx_sw_if_index_set = 0;
5664   u32 bd_id;
5665   u8 bd_id_set = 0;
5666   u8 bvi = 0;
5667   u32 shg = 0;
5668   u8 enable = 1;
5669   int ret;
5670
5671   /* Parse args required to build the message */
5672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5673     {
5674       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5675         rx_sw_if_index_set = 1;
5676       else if (unformat (i, "bd_id %d", &bd_id))
5677         bd_id_set = 1;
5678       else
5679         if (unformat
5680             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5681         rx_sw_if_index_set = 1;
5682       else if (unformat (i, "shg %d", &shg))
5683         ;
5684       else if (unformat (i, "bvi"))
5685         bvi = 1;
5686       else if (unformat (i, "enable"))
5687         enable = 1;
5688       else if (unformat (i, "disable"))
5689         enable = 0;
5690       else
5691         break;
5692     }
5693
5694   if (rx_sw_if_index_set == 0)
5695     {
5696       errmsg ("missing rx interface name or sw_if_index");
5697       return -99;
5698     }
5699
5700   if (enable && (bd_id_set == 0))
5701     {
5702       errmsg ("missing bridge domain");
5703       return -99;
5704     }
5705
5706   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5707
5708   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5709   mp->bd_id = ntohl (bd_id);
5710   mp->shg = (u8) shg;
5711   mp->bvi = bvi;
5712   mp->enable = enable;
5713
5714   S (mp);
5715   W (ret);
5716   return ret;
5717 }
5718
5719 static int
5720 api_bridge_domain_dump (vat_main_t * vam)
5721 {
5722   unformat_input_t *i = vam->input;
5723   vl_api_bridge_domain_dump_t *mp;
5724   vl_api_control_ping_t *mp_ping;
5725   u32 bd_id = ~0;
5726   int ret;
5727
5728   /* Parse args required to build the message */
5729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5730     {
5731       if (unformat (i, "bd_id %d", &bd_id))
5732         ;
5733       else
5734         break;
5735     }
5736
5737   M (BRIDGE_DOMAIN_DUMP, mp);
5738   mp->bd_id = ntohl (bd_id);
5739   S (mp);
5740
5741   /* Use a control ping for synchronization */
5742   M (CONTROL_PING, mp_ping);
5743   S (mp_ping);
5744
5745   W (ret);
5746   return ret;
5747 }
5748
5749 static int
5750 api_bridge_domain_add_del (vat_main_t * vam)
5751 {
5752   unformat_input_t *i = vam->input;
5753   vl_api_bridge_domain_add_del_t *mp;
5754   u32 bd_id = ~0;
5755   u8 is_add = 1;
5756   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5757   u32 mac_age = 0;
5758   int ret;
5759
5760   /* Parse args required to build the message */
5761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5762     {
5763       if (unformat (i, "bd_id %d", &bd_id))
5764         ;
5765       else if (unformat (i, "flood %d", &flood))
5766         ;
5767       else if (unformat (i, "uu-flood %d", &uu_flood))
5768         ;
5769       else if (unformat (i, "forward %d", &forward))
5770         ;
5771       else if (unformat (i, "learn %d", &learn))
5772         ;
5773       else if (unformat (i, "arp-term %d", &arp_term))
5774         ;
5775       else if (unformat (i, "mac-age %d", &mac_age))
5776         ;
5777       else if (unformat (i, "del"))
5778         {
5779           is_add = 0;
5780           flood = uu_flood = forward = learn = 0;
5781         }
5782       else
5783         break;
5784     }
5785
5786   if (bd_id == ~0)
5787     {
5788       errmsg ("missing bridge domain");
5789       return -99;
5790     }
5791
5792   if (mac_age > 255)
5793     {
5794       errmsg ("mac age must be less than 256 ");
5795       return -99;
5796     }
5797
5798   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5799
5800   mp->bd_id = ntohl (bd_id);
5801   mp->flood = flood;
5802   mp->uu_flood = uu_flood;
5803   mp->forward = forward;
5804   mp->learn = learn;
5805   mp->arp_term = arp_term;
5806   mp->is_add = is_add;
5807   mp->mac_age = (u8) mac_age;
5808
5809   S (mp);
5810   W (ret);
5811   return ret;
5812 }
5813
5814 static int
5815 api_l2fib_add_del (vat_main_t * vam)
5816 {
5817   unformat_input_t *i = vam->input;
5818   vl_api_l2fib_add_del_t *mp;
5819   f64 timeout;
5820   u64 mac = 0;
5821   u8 mac_set = 0;
5822   u32 bd_id;
5823   u8 bd_id_set = 0;
5824   u32 sw_if_index = ~0;
5825   u8 sw_if_index_set = 0;
5826   u8 is_add = 1;
5827   u8 static_mac = 0;
5828   u8 filter_mac = 0;
5829   u8 bvi_mac = 0;
5830   int count = 1;
5831   f64 before = 0;
5832   int j;
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5838         mac_set = 1;
5839       else if (unformat (i, "bd_id %d", &bd_id))
5840         bd_id_set = 1;
5841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5842         sw_if_index_set = 1;
5843       else if (unformat (i, "sw_if"))
5844         {
5845           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5846             {
5847               if (unformat
5848                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5849                 sw_if_index_set = 1;
5850             }
5851           else
5852             break;
5853         }
5854       else if (unformat (i, "static"))
5855         static_mac = 1;
5856       else if (unformat (i, "filter"))
5857         {
5858           filter_mac = 1;
5859           static_mac = 1;
5860         }
5861       else if (unformat (i, "bvi"))
5862         {
5863           bvi_mac = 1;
5864           static_mac = 1;
5865         }
5866       else if (unformat (i, "del"))
5867         is_add = 0;
5868       else if (unformat (i, "count %d", &count))
5869         ;
5870       else
5871         break;
5872     }
5873
5874   if (mac_set == 0)
5875     {
5876       errmsg ("missing mac address");
5877       return -99;
5878     }
5879
5880   if (bd_id_set == 0)
5881     {
5882       errmsg ("missing bridge domain");
5883       return -99;
5884     }
5885
5886   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5887     {
5888       errmsg ("missing interface name or sw_if_index");
5889       return -99;
5890     }
5891
5892   if (count > 1)
5893     {
5894       /* Turn on async mode */
5895       vam->async_mode = 1;
5896       vam->async_errors = 0;
5897       before = vat_time_now (vam);
5898     }
5899
5900   for (j = 0; j < count; j++)
5901     {
5902       M (L2FIB_ADD_DEL, mp);
5903
5904       mp->mac = mac;
5905       mp->bd_id = ntohl (bd_id);
5906       mp->is_add = is_add;
5907
5908       if (is_add)
5909         {
5910           mp->sw_if_index = ntohl (sw_if_index);
5911           mp->static_mac = static_mac;
5912           mp->filter_mac = filter_mac;
5913           mp->bvi_mac = bvi_mac;
5914         }
5915       increment_mac_address (&mac);
5916       /* send it... */
5917       S (mp);
5918     }
5919
5920   if (count > 1)
5921     {
5922       vl_api_control_ping_t *mp_ping;
5923       f64 after;
5924
5925       /* Shut off async mode */
5926       vam->async_mode = 0;
5927
5928       M (CONTROL_PING, mp_ping);
5929       S (mp_ping);
5930
5931       timeout = vat_time_now (vam) + 1.0;
5932       while (vat_time_now (vam) < timeout)
5933         if (vam->result_ready == 1)
5934           goto out;
5935       vam->retval = -99;
5936
5937     out:
5938       if (vam->retval == -99)
5939         errmsg ("timeout");
5940
5941       if (vam->async_errors > 0)
5942         {
5943           errmsg ("%d asynchronous errors", vam->async_errors);
5944           vam->retval = -98;
5945         }
5946       vam->async_errors = 0;
5947       after = vat_time_now (vam);
5948
5949       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5950              count, after - before, count / (after - before));
5951     }
5952   else
5953     {
5954       int ret;
5955
5956       /* Wait for a reply... */
5957       W (ret);
5958       return ret;
5959     }
5960   /* Return the good/bad news */
5961   return (vam->retval);
5962 }
5963
5964 static int
5965 api_l2_flags (vat_main_t * vam)
5966 {
5967   unformat_input_t *i = vam->input;
5968   vl_api_l2_flags_t *mp;
5969   u32 sw_if_index;
5970   u32 feature_bitmap = 0;
5971   u8 sw_if_index_set = 0;
5972   int ret;
5973
5974   /* Parse args required to build the message */
5975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5976     {
5977       if (unformat (i, "sw_if_index %d", &sw_if_index))
5978         sw_if_index_set = 1;
5979       else if (unformat (i, "sw_if"))
5980         {
5981           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5982             {
5983               if (unformat
5984                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5985                 sw_if_index_set = 1;
5986             }
5987           else
5988             break;
5989         }
5990       else if (unformat (i, "learn"))
5991         feature_bitmap |= L2INPUT_FEAT_LEARN;
5992       else if (unformat (i, "forward"))
5993         feature_bitmap |= L2INPUT_FEAT_FWD;
5994       else if (unformat (i, "flood"))
5995         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5996       else if (unformat (i, "uu-flood"))
5997         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5998       else
5999         break;
6000     }
6001
6002   if (sw_if_index_set == 0)
6003     {
6004       errmsg ("missing interface name or sw_if_index");
6005       return -99;
6006     }
6007
6008   M (L2_FLAGS, mp);
6009
6010   mp->sw_if_index = ntohl (sw_if_index);
6011   mp->feature_bitmap = ntohl (feature_bitmap);
6012
6013   S (mp);
6014   W (ret);
6015   return ret;
6016 }
6017
6018 static int
6019 api_bridge_flags (vat_main_t * vam)
6020 {
6021   unformat_input_t *i = vam->input;
6022   vl_api_bridge_flags_t *mp;
6023   u32 bd_id;
6024   u8 bd_id_set = 0;
6025   u8 is_set = 1;
6026   u32 flags = 0;
6027   int ret;
6028
6029   /* Parse args required to build the message */
6030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6031     {
6032       if (unformat (i, "bd_id %d", &bd_id))
6033         bd_id_set = 1;
6034       else if (unformat (i, "learn"))
6035         flags |= L2_LEARN;
6036       else if (unformat (i, "forward"))
6037         flags |= L2_FWD;
6038       else if (unformat (i, "flood"))
6039         flags |= L2_FLOOD;
6040       else if (unformat (i, "uu-flood"))
6041         flags |= L2_UU_FLOOD;
6042       else if (unformat (i, "arp-term"))
6043         flags |= L2_ARP_TERM;
6044       else if (unformat (i, "off"))
6045         is_set = 0;
6046       else if (unformat (i, "disable"))
6047         is_set = 0;
6048       else
6049         break;
6050     }
6051
6052   if (bd_id_set == 0)
6053     {
6054       errmsg ("missing bridge domain");
6055       return -99;
6056     }
6057
6058   M (BRIDGE_FLAGS, mp);
6059
6060   mp->bd_id = ntohl (bd_id);
6061   mp->feature_bitmap = ntohl (flags);
6062   mp->is_set = is_set;
6063
6064   S (mp);
6065   W (ret);
6066   return ret;
6067 }
6068
6069 static int
6070 api_bd_ip_mac_add_del (vat_main_t * vam)
6071 {
6072   unformat_input_t *i = vam->input;
6073   vl_api_bd_ip_mac_add_del_t *mp;
6074   u32 bd_id;
6075   u8 is_ipv6 = 0;
6076   u8 is_add = 1;
6077   u8 bd_id_set = 0;
6078   u8 ip_set = 0;
6079   u8 mac_set = 0;
6080   ip4_address_t v4addr;
6081   ip6_address_t v6addr;
6082   u8 macaddr[6];
6083   int ret;
6084
6085
6086   /* Parse args required to build the message */
6087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6088     {
6089       if (unformat (i, "bd_id %d", &bd_id))
6090         {
6091           bd_id_set++;
6092         }
6093       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6094         {
6095           ip_set++;
6096         }
6097       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6098         {
6099           ip_set++;
6100           is_ipv6++;
6101         }
6102       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6103         {
6104           mac_set++;
6105         }
6106       else if (unformat (i, "del"))
6107         is_add = 0;
6108       else
6109         break;
6110     }
6111
6112   if (bd_id_set == 0)
6113     {
6114       errmsg ("missing bridge domain");
6115       return -99;
6116     }
6117   else if (ip_set == 0)
6118     {
6119       errmsg ("missing IP address");
6120       return -99;
6121     }
6122   else if (mac_set == 0)
6123     {
6124       errmsg ("missing MAC address");
6125       return -99;
6126     }
6127
6128   M (BD_IP_MAC_ADD_DEL, mp);
6129
6130   mp->bd_id = ntohl (bd_id);
6131   mp->is_ipv6 = is_ipv6;
6132   mp->is_add = is_add;
6133   if (is_ipv6)
6134     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6135   else
6136     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6137   clib_memcpy (mp->mac_address, macaddr, 6);
6138   S (mp);
6139   W (ret);
6140   return ret;
6141 }
6142
6143 static int
6144 api_tap_connect (vat_main_t * vam)
6145 {
6146   unformat_input_t *i = vam->input;
6147   vl_api_tap_connect_t *mp;
6148   u8 mac_address[6];
6149   u8 random_mac = 1;
6150   u8 name_set = 0;
6151   u8 *tap_name;
6152   u8 *tag = 0;
6153   ip4_address_t ip4_address;
6154   u32 ip4_mask_width;
6155   int ip4_address_set = 0;
6156   ip6_address_t ip6_address;
6157   u32 ip6_mask_width;
6158   int ip6_address_set = 0;
6159   int ret;
6160
6161   memset (mac_address, 0, sizeof (mac_address));
6162
6163   /* Parse args required to build the message */
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6167         {
6168           random_mac = 0;
6169         }
6170       else if (unformat (i, "random-mac"))
6171         random_mac = 1;
6172       else if (unformat (i, "tapname %s", &tap_name))
6173         name_set = 1;
6174       else if (unformat (i, "tag %s", &tag))
6175         ;
6176       else if (unformat (i, "address %U/%d",
6177                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6178         ip4_address_set = 1;
6179       else if (unformat (i, "address %U/%d",
6180                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6181         ip6_address_set = 1;
6182       else
6183         break;
6184     }
6185
6186   if (name_set == 0)
6187     {
6188       errmsg ("missing tap name");
6189       return -99;
6190     }
6191   if (vec_len (tap_name) > 63)
6192     {
6193       errmsg ("tap name too long");
6194       return -99;
6195     }
6196   vec_add1 (tap_name, 0);
6197
6198   if (vec_len (tag) > 63)
6199     {
6200       errmsg ("tag too long");
6201       return -99;
6202     }
6203
6204   /* Construct the API message */
6205   M (TAP_CONNECT, mp);
6206
6207   mp->use_random_mac = random_mac;
6208   clib_memcpy (mp->mac_address, mac_address, 6);
6209   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6210   if (tag)
6211     clib_memcpy (mp->tag, tag, vec_len (tag));
6212
6213   if (ip4_address_set)
6214     {
6215       mp->ip4_address_set = 1;
6216       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6217       mp->ip4_mask_width = ip4_mask_width;
6218     }
6219   if (ip6_address_set)
6220     {
6221       mp->ip6_address_set = 1;
6222       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6223       mp->ip6_mask_width = ip6_mask_width;
6224     }
6225
6226   vec_free (tap_name);
6227   vec_free (tag);
6228
6229   /* send it... */
6230   S (mp);
6231
6232   /* Wait for a reply... */
6233   W (ret);
6234   return ret;
6235 }
6236
6237 static int
6238 api_tap_modify (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_tap_modify_t *mp;
6242   u8 mac_address[6];
6243   u8 random_mac = 1;
6244   u8 name_set = 0;
6245   u8 *tap_name;
6246   u32 sw_if_index = ~0;
6247   u8 sw_if_index_set = 0;
6248   int ret;
6249
6250   memset (mac_address, 0, sizeof (mac_address));
6251
6252   /* Parse args required to build the message */
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set = 1;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set = 1;
6259       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6260         {
6261           random_mac = 0;
6262         }
6263       else if (unformat (i, "random-mac"))
6264         random_mac = 1;
6265       else if (unformat (i, "tapname %s", &tap_name))
6266         name_set = 1;
6267       else
6268         break;
6269     }
6270
6271   if (sw_if_index_set == 0)
6272     {
6273       errmsg ("missing vpp interface name");
6274       return -99;
6275     }
6276   if (name_set == 0)
6277     {
6278       errmsg ("missing tap name");
6279       return -99;
6280     }
6281   if (vec_len (tap_name) > 63)
6282     {
6283       errmsg ("tap name too long");
6284     }
6285   vec_add1 (tap_name, 0);
6286
6287   /* Construct the API message */
6288   M (TAP_MODIFY, mp);
6289
6290   mp->use_random_mac = random_mac;
6291   mp->sw_if_index = ntohl (sw_if_index);
6292   clib_memcpy (mp->mac_address, mac_address, 6);
6293   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6294   vec_free (tap_name);
6295
6296   /* send it... */
6297   S (mp);
6298
6299   /* Wait for a reply... */
6300   W (ret);
6301   return ret;
6302 }
6303
6304 static int
6305 api_tap_delete (vat_main_t * vam)
6306 {
6307   unformat_input_t *i = vam->input;
6308   vl_api_tap_delete_t *mp;
6309   u32 sw_if_index = ~0;
6310   u8 sw_if_index_set = 0;
6311   int ret;
6312
6313   /* Parse args required to build the message */
6314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6315     {
6316       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6317         sw_if_index_set = 1;
6318       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6319         sw_if_index_set = 1;
6320       else
6321         break;
6322     }
6323
6324   if (sw_if_index_set == 0)
6325     {
6326       errmsg ("missing vpp interface name");
6327       return -99;
6328     }
6329
6330   /* Construct the API message */
6331   M (TAP_DELETE, mp);
6332
6333   mp->sw_if_index = ntohl (sw_if_index);
6334
6335   /* send it... */
6336   S (mp);
6337
6338   /* Wait for a reply... */
6339   W (ret);
6340   return ret;
6341 }
6342
6343 static int
6344 api_ip_add_del_route (vat_main_t * vam)
6345 {
6346   unformat_input_t *i = vam->input;
6347   vl_api_ip_add_del_route_t *mp;
6348   u32 sw_if_index = ~0, vrf_id = 0;
6349   u8 is_ipv6 = 0;
6350   u8 is_local = 0, is_drop = 0;
6351   u8 is_unreach = 0, is_prohibit = 0;
6352   u8 create_vrf_if_needed = 0;
6353   u8 is_add = 1;
6354   u32 next_hop_weight = 1;
6355   u8 not_last = 0;
6356   u8 is_multipath = 0;
6357   u8 address_set = 0;
6358   u8 address_length_set = 0;
6359   u32 next_hop_table_id = 0;
6360   u32 resolve_attempts = 0;
6361   u32 dst_address_length = 0;
6362   u8 next_hop_set = 0;
6363   ip4_address_t v4_dst_address, v4_next_hop_address;
6364   ip6_address_t v6_dst_address, v6_next_hop_address;
6365   int count = 1;
6366   int j;
6367   f64 before = 0;
6368   u32 random_add_del = 0;
6369   u32 *random_vector = 0;
6370   uword *random_hash;
6371   u32 random_seed = 0xdeaddabe;
6372   u32 classify_table_index = ~0;
6373   u8 is_classify = 0;
6374   u8 resolve_host = 0, resolve_attached = 0;
6375   mpls_label_t *next_hop_out_label_stack = NULL;
6376   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6377   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6378
6379   /* Parse args required to build the message */
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383         ;
6384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385         ;
6386       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6387         {
6388           address_set = 1;
6389           is_ipv6 = 0;
6390         }
6391       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6392         {
6393           address_set = 1;
6394           is_ipv6 = 1;
6395         }
6396       else if (unformat (i, "/%d", &dst_address_length))
6397         {
6398           address_length_set = 1;
6399         }
6400
6401       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6402                                          &v4_next_hop_address))
6403         {
6404           next_hop_set = 1;
6405         }
6406       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6407                                          &v6_next_hop_address))
6408         {
6409           next_hop_set = 1;
6410         }
6411       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6412         ;
6413       else if (unformat (i, "weight %d", &next_hop_weight))
6414         ;
6415       else if (unformat (i, "drop"))
6416         {
6417           is_drop = 1;
6418         }
6419       else if (unformat (i, "null-send-unreach"))
6420         {
6421           is_unreach = 1;
6422         }
6423       else if (unformat (i, "null-send-prohibit"))
6424         {
6425           is_prohibit = 1;
6426         }
6427       else if (unformat (i, "local"))
6428         {
6429           is_local = 1;
6430         }
6431       else if (unformat (i, "classify %d", &classify_table_index))
6432         {
6433           is_classify = 1;
6434         }
6435       else if (unformat (i, "del"))
6436         is_add = 0;
6437       else if (unformat (i, "add"))
6438         is_add = 1;
6439       else if (unformat (i, "not-last"))
6440         not_last = 1;
6441       else if (unformat (i, "resolve-via-host"))
6442         resolve_host = 1;
6443       else if (unformat (i, "resolve-via-attached"))
6444         resolve_attached = 1;
6445       else if (unformat (i, "multipath"))
6446         is_multipath = 1;
6447       else if (unformat (i, "vrf %d", &vrf_id))
6448         ;
6449       else if (unformat (i, "create-vrf"))
6450         create_vrf_if_needed = 1;
6451       else if (unformat (i, "count %d", &count))
6452         ;
6453       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6454         ;
6455       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6456         ;
6457       else if (unformat (i, "out-label %d", &next_hop_out_label))
6458         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6459       else if (unformat (i, "via-label %d", &next_hop_via_label))
6460         ;
6461       else if (unformat (i, "random"))
6462         random_add_del = 1;
6463       else if (unformat (i, "seed %d", &random_seed))
6464         ;
6465       else
6466         {
6467           clib_warning ("parse error '%U'", format_unformat_error, i);
6468           return -99;
6469         }
6470     }
6471
6472   if (!next_hop_set && !is_drop && !is_local &&
6473       !is_classify && !is_unreach && !is_prohibit &&
6474       MPLS_LABEL_INVALID == next_hop_via_label)
6475     {
6476       errmsg
6477         ("next hop / local / drop / unreach / prohibit / classify not set");
6478       return -99;
6479     }
6480
6481   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6482     {
6483       errmsg ("next hop and next-hop via label set");
6484       return -99;
6485     }
6486   if (address_set == 0)
6487     {
6488       errmsg ("missing addresses");
6489       return -99;
6490     }
6491
6492   if (address_length_set == 0)
6493     {
6494       errmsg ("missing address length");
6495       return -99;
6496     }
6497
6498   /* Generate a pile of unique, random routes */
6499   if (random_add_del)
6500     {
6501       u32 this_random_address;
6502       random_hash = hash_create (count, sizeof (uword));
6503
6504       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6505       for (j = 0; j <= count; j++)
6506         {
6507           do
6508             {
6509               this_random_address = random_u32 (&random_seed);
6510               this_random_address =
6511                 clib_host_to_net_u32 (this_random_address);
6512             }
6513           while (hash_get (random_hash, this_random_address));
6514           vec_add1 (random_vector, this_random_address);
6515           hash_set (random_hash, this_random_address, 1);
6516         }
6517       hash_free (random_hash);
6518       v4_dst_address.as_u32 = random_vector[0];
6519     }
6520
6521   if (count > 1)
6522     {
6523       /* Turn on async mode */
6524       vam->async_mode = 1;
6525       vam->async_errors = 0;
6526       before = vat_time_now (vam);
6527     }
6528
6529   for (j = 0; j < count; j++)
6530     {
6531       /* Construct the API message */
6532       M2 (IP_ADD_DEL_ROUTE, mp,
6533           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6534
6535       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6536       mp->table_id = ntohl (vrf_id);
6537       mp->create_vrf_if_needed = create_vrf_if_needed;
6538
6539       mp->is_add = is_add;
6540       mp->is_drop = is_drop;
6541       mp->is_unreach = is_unreach;
6542       mp->is_prohibit = is_prohibit;
6543       mp->is_ipv6 = is_ipv6;
6544       mp->is_local = is_local;
6545       mp->is_classify = is_classify;
6546       mp->is_multipath = is_multipath;
6547       mp->is_resolve_host = resolve_host;
6548       mp->is_resolve_attached = resolve_attached;
6549       mp->not_last = not_last;
6550       mp->next_hop_weight = next_hop_weight;
6551       mp->dst_address_length = dst_address_length;
6552       mp->next_hop_table_id = ntohl (next_hop_table_id);
6553       mp->classify_table_index = ntohl (classify_table_index);
6554       mp->next_hop_via_label = ntohl (next_hop_via_label);
6555       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6556       if (0 != mp->next_hop_n_out_labels)
6557         {
6558           memcpy (mp->next_hop_out_label_stack,
6559                   next_hop_out_label_stack,
6560                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6561           vec_free (next_hop_out_label_stack);
6562         }
6563
6564       if (is_ipv6)
6565         {
6566           clib_memcpy (mp->dst_address, &v6_dst_address,
6567                        sizeof (v6_dst_address));
6568           if (next_hop_set)
6569             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6570                          sizeof (v6_next_hop_address));
6571           increment_v6_address (&v6_dst_address);
6572         }
6573       else
6574         {
6575           clib_memcpy (mp->dst_address, &v4_dst_address,
6576                        sizeof (v4_dst_address));
6577           if (next_hop_set)
6578             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6579                          sizeof (v4_next_hop_address));
6580           if (random_add_del)
6581             v4_dst_address.as_u32 = random_vector[j + 1];
6582           else
6583             increment_v4_address (&v4_dst_address);
6584         }
6585       /* send it... */
6586       S (mp);
6587       /* If we receive SIGTERM, stop now... */
6588       if (vam->do_exit)
6589         break;
6590     }
6591
6592   /* When testing multiple add/del ops, use a control-ping to sync */
6593   if (count > 1)
6594     {
6595       vl_api_control_ping_t *mp_ping;
6596       f64 after;
6597       f64 timeout;
6598
6599       /* Shut off async mode */
6600       vam->async_mode = 0;
6601
6602       M (CONTROL_PING, mp_ping);
6603       S (mp_ping);
6604
6605       timeout = vat_time_now (vam) + 1.0;
6606       while (vat_time_now (vam) < timeout)
6607         if (vam->result_ready == 1)
6608           goto out;
6609       vam->retval = -99;
6610
6611     out:
6612       if (vam->retval == -99)
6613         errmsg ("timeout");
6614
6615       if (vam->async_errors > 0)
6616         {
6617           errmsg ("%d asynchronous errors", vam->async_errors);
6618           vam->retval = -98;
6619         }
6620       vam->async_errors = 0;
6621       after = vat_time_now (vam);
6622
6623       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6624       if (j > 0)
6625         count = j;
6626
6627       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6628              count, after - before, count / (after - before));
6629     }
6630   else
6631     {
6632       int ret;
6633
6634       /* Wait for a reply... */
6635       W (ret);
6636       return ret;
6637     }
6638
6639   /* Return the good/bad news */
6640   return (vam->retval);
6641 }
6642
6643 static int
6644 api_ip_mroute_add_del (vat_main_t * vam)
6645 {
6646   unformat_input_t *i = vam->input;
6647   vl_api_ip_mroute_add_del_t *mp;
6648   u32 sw_if_index = ~0, vrf_id = 0;
6649   u8 is_ipv6 = 0;
6650   u8 is_local = 0;
6651   u8 create_vrf_if_needed = 0;
6652   u8 is_add = 1;
6653   u8 address_set = 0;
6654   u32 grp_address_length = 0;
6655   ip4_address_t v4_grp_address, v4_src_address;
6656   ip6_address_t v6_grp_address, v6_src_address;
6657   mfib_itf_flags_t iflags = 0;
6658   mfib_entry_flags_t eflags = 0;
6659   int ret;
6660
6661   /* Parse args required to build the message */
6662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663     {
6664       if (unformat (i, "sw_if_index %d", &sw_if_index))
6665         ;
6666       else if (unformat (i, "%U %U",
6667                          unformat_ip4_address, &v4_src_address,
6668                          unformat_ip4_address, &v4_grp_address))
6669         {
6670           grp_address_length = 64;
6671           address_set = 1;
6672           is_ipv6 = 0;
6673         }
6674       else if (unformat (i, "%U %U",
6675                          unformat_ip6_address, &v6_src_address,
6676                          unformat_ip6_address, &v6_grp_address))
6677         {
6678           grp_address_length = 256;
6679           address_set = 1;
6680           is_ipv6 = 1;
6681         }
6682       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6683         {
6684           memset (&v4_src_address, 0, sizeof (v4_src_address));
6685           grp_address_length = 32;
6686           address_set = 1;
6687           is_ipv6 = 0;
6688         }
6689       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6690         {
6691           memset (&v6_src_address, 0, sizeof (v6_src_address));
6692           grp_address_length = 128;
6693           address_set = 1;
6694           is_ipv6 = 1;
6695         }
6696       else if (unformat (i, "/%d", &grp_address_length))
6697         ;
6698       else if (unformat (i, "local"))
6699         {
6700           is_local = 1;
6701         }
6702       else if (unformat (i, "del"))
6703         is_add = 0;
6704       else if (unformat (i, "add"))
6705         is_add = 1;
6706       else if (unformat (i, "vrf %d", &vrf_id))
6707         ;
6708       else if (unformat (i, "create-vrf"))
6709         create_vrf_if_needed = 1;
6710       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6711         ;
6712       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6713         ;
6714       else
6715         {
6716           clib_warning ("parse error '%U'", format_unformat_error, i);
6717           return -99;
6718         }
6719     }
6720
6721   if (address_set == 0)
6722     {
6723       errmsg ("missing addresses\n");
6724       return -99;
6725     }
6726
6727   /* Construct the API message */
6728   M (IP_MROUTE_ADD_DEL, mp);
6729
6730   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6731   mp->table_id = ntohl (vrf_id);
6732   mp->create_vrf_if_needed = create_vrf_if_needed;
6733
6734   mp->is_add = is_add;
6735   mp->is_ipv6 = is_ipv6;
6736   mp->is_local = is_local;
6737   mp->itf_flags = ntohl (iflags);
6738   mp->entry_flags = ntohl (eflags);
6739   mp->grp_address_length = grp_address_length;
6740   mp->grp_address_length = ntohs (mp->grp_address_length);
6741
6742   if (is_ipv6)
6743     {
6744       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6745       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6746     }
6747   else
6748     {
6749       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6750       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6751
6752     }
6753
6754   /* send it... */
6755   S (mp);
6756   /* Wait for a reply... */
6757   W (ret);
6758   return ret;
6759 }
6760
6761 static int
6762 api_mpls_route_add_del (vat_main_t * vam)
6763 {
6764   unformat_input_t *i = vam->input;
6765   vl_api_mpls_route_add_del_t *mp;
6766   u32 sw_if_index = ~0, table_id = 0;
6767   u8 create_table_if_needed = 0;
6768   u8 is_add = 1;
6769   u32 next_hop_weight = 1;
6770   u8 is_multipath = 0;
6771   u32 next_hop_table_id = 0;
6772   u8 next_hop_set = 0;
6773   ip4_address_t v4_next_hop_address = {
6774     .as_u32 = 0,
6775   };
6776   ip6_address_t v6_next_hop_address = { {0} };
6777   int count = 1;
6778   int j;
6779   f64 before = 0;
6780   u32 classify_table_index = ~0;
6781   u8 is_classify = 0;
6782   u8 resolve_host = 0, resolve_attached = 0;
6783   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6784   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6785   mpls_label_t *next_hop_out_label_stack = NULL;
6786   mpls_label_t local_label = MPLS_LABEL_INVALID;
6787   u8 is_eos = 0;
6788   u8 next_hop_proto_is_ip4 = 1;
6789
6790   /* Parse args required to build the message */
6791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6792     {
6793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6794         ;
6795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6796         ;
6797       else if (unformat (i, "%d", &local_label))
6798         ;
6799       else if (unformat (i, "eos"))
6800         is_eos = 1;
6801       else if (unformat (i, "non-eos"))
6802         is_eos = 0;
6803       else if (unformat (i, "via %U", unformat_ip4_address,
6804                          &v4_next_hop_address))
6805         {
6806           next_hop_set = 1;
6807           next_hop_proto_is_ip4 = 1;
6808         }
6809       else if (unformat (i, "via %U", unformat_ip6_address,
6810                          &v6_next_hop_address))
6811         {
6812           next_hop_set = 1;
6813           next_hop_proto_is_ip4 = 0;
6814         }
6815       else if (unformat (i, "weight %d", &next_hop_weight))
6816         ;
6817       else if (unformat (i, "create-table"))
6818         create_table_if_needed = 1;
6819       else if (unformat (i, "classify %d", &classify_table_index))
6820         {
6821           is_classify = 1;
6822         }
6823       else if (unformat (i, "del"))
6824         is_add = 0;
6825       else if (unformat (i, "add"))
6826         is_add = 1;
6827       else if (unformat (i, "resolve-via-host"))
6828         resolve_host = 1;
6829       else if (unformat (i, "resolve-via-attached"))
6830         resolve_attached = 1;
6831       else if (unformat (i, "multipath"))
6832         is_multipath = 1;
6833       else if (unformat (i, "count %d", &count))
6834         ;
6835       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6836         {
6837           next_hop_set = 1;
6838           next_hop_proto_is_ip4 = 1;
6839         }
6840       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6841         {
6842           next_hop_set = 1;
6843           next_hop_proto_is_ip4 = 0;
6844         }
6845       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6846         ;
6847       else if (unformat (i, "via-label %d", &next_hop_via_label))
6848         ;
6849       else if (unformat (i, "out-label %d", &next_hop_out_label))
6850         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6851       else
6852         {
6853           clib_warning ("parse error '%U'", format_unformat_error, i);
6854           return -99;
6855         }
6856     }
6857
6858   if (!next_hop_set && !is_classify)
6859     {
6860       errmsg ("next hop / classify not set");
6861       return -99;
6862     }
6863
6864   if (MPLS_LABEL_INVALID == local_label)
6865     {
6866       errmsg ("missing label");
6867       return -99;
6868     }
6869
6870   if (count > 1)
6871     {
6872       /* Turn on async mode */
6873       vam->async_mode = 1;
6874       vam->async_errors = 0;
6875       before = vat_time_now (vam);
6876     }
6877
6878   for (j = 0; j < count; j++)
6879     {
6880       /* Construct the API message */
6881       M2 (MPLS_ROUTE_ADD_DEL, mp,
6882           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6883
6884       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6885       mp->mr_table_id = ntohl (table_id);
6886       mp->mr_create_table_if_needed = create_table_if_needed;
6887
6888       mp->mr_is_add = is_add;
6889       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6890       mp->mr_is_classify = is_classify;
6891       mp->mr_is_multipath = is_multipath;
6892       mp->mr_is_resolve_host = resolve_host;
6893       mp->mr_is_resolve_attached = resolve_attached;
6894       mp->mr_next_hop_weight = next_hop_weight;
6895       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6896       mp->mr_classify_table_index = ntohl (classify_table_index);
6897       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6898       mp->mr_label = ntohl (local_label);
6899       mp->mr_eos = is_eos;
6900
6901       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6902       if (0 != mp->mr_next_hop_n_out_labels)
6903         {
6904           memcpy (mp->mr_next_hop_out_label_stack,
6905                   next_hop_out_label_stack,
6906                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6907           vec_free (next_hop_out_label_stack);
6908         }
6909
6910       if (next_hop_set)
6911         {
6912           if (next_hop_proto_is_ip4)
6913             {
6914               clib_memcpy (mp->mr_next_hop,
6915                            &v4_next_hop_address,
6916                            sizeof (v4_next_hop_address));
6917             }
6918           else
6919             {
6920               clib_memcpy (mp->mr_next_hop,
6921                            &v6_next_hop_address,
6922                            sizeof (v6_next_hop_address));
6923             }
6924         }
6925       local_label++;
6926
6927       /* send it... */
6928       S (mp);
6929       /* If we receive SIGTERM, stop now... */
6930       if (vam->do_exit)
6931         break;
6932     }
6933
6934   /* When testing multiple add/del ops, use a control-ping to sync */
6935   if (count > 1)
6936     {
6937       vl_api_control_ping_t *mp_ping;
6938       f64 after;
6939       f64 timeout;
6940
6941       /* Shut off async mode */
6942       vam->async_mode = 0;
6943
6944       M (CONTROL_PING, mp_ping);
6945       S (mp_ping);
6946
6947       timeout = vat_time_now (vam) + 1.0;
6948       while (vat_time_now (vam) < timeout)
6949         if (vam->result_ready == 1)
6950           goto out;
6951       vam->retval = -99;
6952
6953     out:
6954       if (vam->retval == -99)
6955         errmsg ("timeout");
6956
6957       if (vam->async_errors > 0)
6958         {
6959           errmsg ("%d asynchronous errors", vam->async_errors);
6960           vam->retval = -98;
6961         }
6962       vam->async_errors = 0;
6963       after = vat_time_now (vam);
6964
6965       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6966       if (j > 0)
6967         count = j;
6968
6969       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6970              count, after - before, count / (after - before));
6971     }
6972   else
6973     {
6974       int ret;
6975
6976       /* Wait for a reply... */
6977       W (ret);
6978       return ret;
6979     }
6980
6981   /* Return the good/bad news */
6982   return (vam->retval);
6983 }
6984
6985 static int
6986 api_mpls_ip_bind_unbind (vat_main_t * vam)
6987 {
6988   unformat_input_t *i = vam->input;
6989   vl_api_mpls_ip_bind_unbind_t *mp;
6990   u32 ip_table_id = 0;
6991   u8 create_table_if_needed = 0;
6992   u8 is_bind = 1;
6993   u8 is_ip4 = 1;
6994   ip4_address_t v4_address;
6995   ip6_address_t v6_address;
6996   u32 address_length;
6997   u8 address_set = 0;
6998   mpls_label_t local_label = MPLS_LABEL_INVALID;
6999   int ret;
7000
7001   /* Parse args required to build the message */
7002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003     {
7004       if (unformat (i, "%U/%d", unformat_ip4_address,
7005                     &v4_address, &address_length))
7006         {
7007           is_ip4 = 1;
7008           address_set = 1;
7009         }
7010       else if (unformat (i, "%U/%d", unformat_ip6_address,
7011                          &v6_address, &address_length))
7012         {
7013           is_ip4 = 0;
7014           address_set = 1;
7015         }
7016       else if (unformat (i, "%d", &local_label))
7017         ;
7018       else if (unformat (i, "create-table"))
7019         create_table_if_needed = 1;
7020       else if (unformat (i, "table-id %d", &ip_table_id))
7021         ;
7022       else if (unformat (i, "unbind"))
7023         is_bind = 0;
7024       else if (unformat (i, "bind"))
7025         is_bind = 1;
7026       else
7027         {
7028           clib_warning ("parse error '%U'", format_unformat_error, i);
7029           return -99;
7030         }
7031     }
7032
7033   if (!address_set)
7034     {
7035       errmsg ("IP addres not set");
7036       return -99;
7037     }
7038
7039   if (MPLS_LABEL_INVALID == local_label)
7040     {
7041       errmsg ("missing label");
7042       return -99;
7043     }
7044
7045   /* Construct the API message */
7046   M (MPLS_IP_BIND_UNBIND, mp);
7047
7048   mp->mb_create_table_if_needed = create_table_if_needed;
7049   mp->mb_is_bind = is_bind;
7050   mp->mb_is_ip4 = is_ip4;
7051   mp->mb_ip_table_id = ntohl (ip_table_id);
7052   mp->mb_mpls_table_id = 0;
7053   mp->mb_label = ntohl (local_label);
7054   mp->mb_address_length = address_length;
7055
7056   if (is_ip4)
7057     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7058   else
7059     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7060
7061   /* send it... */
7062   S (mp);
7063
7064   /* Wait for a reply... */
7065   W (ret);
7066   return ret;
7067 }
7068
7069 static int
7070 api_proxy_arp_add_del (vat_main_t * vam)
7071 {
7072   unformat_input_t *i = vam->input;
7073   vl_api_proxy_arp_add_del_t *mp;
7074   u32 vrf_id = 0;
7075   u8 is_add = 1;
7076   ip4_address_t lo, hi;
7077   u8 range_set = 0;
7078   int ret;
7079
7080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7081     {
7082       if (unformat (i, "vrf %d", &vrf_id))
7083         ;
7084       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7085                          unformat_ip4_address, &hi))
7086         range_set = 1;
7087       else if (unformat (i, "del"))
7088         is_add = 0;
7089       else
7090         {
7091           clib_warning ("parse error '%U'", format_unformat_error, i);
7092           return -99;
7093         }
7094     }
7095
7096   if (range_set == 0)
7097     {
7098       errmsg ("address range not set");
7099       return -99;
7100     }
7101
7102   M (PROXY_ARP_ADD_DEL, mp);
7103
7104   mp->vrf_id = ntohl (vrf_id);
7105   mp->is_add = is_add;
7106   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7107   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7108
7109   S (mp);
7110   W (ret);
7111   return ret;
7112 }
7113
7114 static int
7115 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7116 {
7117   unformat_input_t *i = vam->input;
7118   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7119   u32 sw_if_index;
7120   u8 enable = 1;
7121   u8 sw_if_index_set = 0;
7122   int ret;
7123
7124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7125     {
7126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7127         sw_if_index_set = 1;
7128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7129         sw_if_index_set = 1;
7130       else if (unformat (i, "enable"))
7131         enable = 1;
7132       else if (unformat (i, "disable"))
7133         enable = 0;
7134       else
7135         {
7136           clib_warning ("parse error '%U'", format_unformat_error, i);
7137           return -99;
7138         }
7139     }
7140
7141   if (sw_if_index_set == 0)
7142     {
7143       errmsg ("missing interface name or sw_if_index");
7144       return -99;
7145     }
7146
7147   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7148
7149   mp->sw_if_index = ntohl (sw_if_index);
7150   mp->enable_disable = enable;
7151
7152   S (mp);
7153   W (ret);
7154   return ret;
7155 }
7156
7157 static int
7158 api_mpls_tunnel_add_del (vat_main_t * vam)
7159 {
7160   unformat_input_t *i = vam->input;
7161   vl_api_mpls_tunnel_add_del_t *mp;
7162
7163   u8 is_add = 1;
7164   u8 l2_only = 0;
7165   u32 sw_if_index = ~0;
7166   u32 next_hop_sw_if_index = ~0;
7167   u32 next_hop_proto_is_ip4 = 1;
7168
7169   u32 next_hop_table_id = 0;
7170   ip4_address_t v4_next_hop_address = {
7171     .as_u32 = 0,
7172   };
7173   ip6_address_t v6_next_hop_address = { {0} };
7174   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7175   int ret;
7176
7177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7178     {
7179       if (unformat (i, "add"))
7180         is_add = 1;
7181       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7182         is_add = 0;
7183       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7184         ;
7185       else if (unformat (i, "via %U",
7186                          unformat_ip4_address, &v4_next_hop_address))
7187         {
7188           next_hop_proto_is_ip4 = 1;
7189         }
7190       else if (unformat (i, "via %U",
7191                          unformat_ip6_address, &v6_next_hop_address))
7192         {
7193           next_hop_proto_is_ip4 = 0;
7194         }
7195       else if (unformat (i, "l2-only"))
7196         l2_only = 1;
7197       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7198         ;
7199       else if (unformat (i, "out-label %d", &next_hop_out_label))
7200         vec_add1 (labels, ntohl (next_hop_out_label));
7201       else
7202         {
7203           clib_warning ("parse error '%U'", format_unformat_error, i);
7204           return -99;
7205         }
7206     }
7207
7208   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7209
7210   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7211   mp->mt_sw_if_index = ntohl (sw_if_index);
7212   mp->mt_is_add = is_add;
7213   mp->mt_l2_only = l2_only;
7214   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7215   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7216
7217   mp->mt_next_hop_n_out_labels = vec_len (labels);
7218
7219   if (0 != mp->mt_next_hop_n_out_labels)
7220     {
7221       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7222                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7223       vec_free (labels);
7224     }
7225
7226   if (next_hop_proto_is_ip4)
7227     {
7228       clib_memcpy (mp->mt_next_hop,
7229                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7230     }
7231   else
7232     {
7233       clib_memcpy (mp->mt_next_hop,
7234                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7235     }
7236
7237   S (mp);
7238   W (ret);
7239   return ret;
7240 }
7241
7242 static int
7243 api_sw_interface_set_unnumbered (vat_main_t * vam)
7244 {
7245   unformat_input_t *i = vam->input;
7246   vl_api_sw_interface_set_unnumbered_t *mp;
7247   u32 sw_if_index;
7248   u32 unnum_sw_index = ~0;
7249   u8 is_add = 1;
7250   u8 sw_if_index_set = 0;
7251   int ret;
7252
7253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7254     {
7255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7256         sw_if_index_set = 1;
7257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7258         sw_if_index_set = 1;
7259       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7260         ;
7261       else if (unformat (i, "del"))
7262         is_add = 0;
7263       else
7264         {
7265           clib_warning ("parse error '%U'", format_unformat_error, i);
7266           return -99;
7267         }
7268     }
7269
7270   if (sw_if_index_set == 0)
7271     {
7272       errmsg ("missing interface name or sw_if_index");
7273       return -99;
7274     }
7275
7276   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7277
7278   mp->sw_if_index = ntohl (sw_if_index);
7279   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7280   mp->is_add = is_add;
7281
7282   S (mp);
7283   W (ret);
7284   return ret;
7285 }
7286
7287 static int
7288 api_ip_neighbor_add_del (vat_main_t * vam)
7289 {
7290   unformat_input_t *i = vam->input;
7291   vl_api_ip_neighbor_add_del_t *mp;
7292   u32 sw_if_index;
7293   u8 sw_if_index_set = 0;
7294   u32 vrf_id = 0;
7295   u8 is_add = 1;
7296   u8 is_static = 0;
7297   u8 mac_address[6];
7298   u8 mac_set = 0;
7299   u8 v4_address_set = 0;
7300   u8 v6_address_set = 0;
7301   ip4_address_t v4address;
7302   ip6_address_t v6address;
7303   int ret;
7304
7305   memset (mac_address, 0, sizeof (mac_address));
7306
7307   /* Parse args required to build the message */
7308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7309     {
7310       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7311         {
7312           mac_set = 1;
7313         }
7314       else if (unformat (i, "del"))
7315         is_add = 0;
7316       else
7317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7318         sw_if_index_set = 1;
7319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7320         sw_if_index_set = 1;
7321       else if (unformat (i, "is_static"))
7322         is_static = 1;
7323       else if (unformat (i, "vrf %d", &vrf_id))
7324         ;
7325       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7326         v4_address_set = 1;
7327       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7328         v6_address_set = 1;
7329       else
7330         {
7331           clib_warning ("parse error '%U'", format_unformat_error, i);
7332           return -99;
7333         }
7334     }
7335
7336   if (sw_if_index_set == 0)
7337     {
7338       errmsg ("missing interface name or sw_if_index");
7339       return -99;
7340     }
7341   if (v4_address_set && v6_address_set)
7342     {
7343       errmsg ("both v4 and v6 addresses set");
7344       return -99;
7345     }
7346   if (!v4_address_set && !v6_address_set)
7347     {
7348       errmsg ("no address set");
7349       return -99;
7350     }
7351
7352   /* Construct the API message */
7353   M (IP_NEIGHBOR_ADD_DEL, mp);
7354
7355   mp->sw_if_index = ntohl (sw_if_index);
7356   mp->is_add = is_add;
7357   mp->vrf_id = ntohl (vrf_id);
7358   mp->is_static = is_static;
7359   if (mac_set)
7360     clib_memcpy (mp->mac_address, mac_address, 6);
7361   if (v6_address_set)
7362     {
7363       mp->is_ipv6 = 1;
7364       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7365     }
7366   else
7367     {
7368       /* mp->is_ipv6 = 0; via memset in M macro above */
7369       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7370     }
7371
7372   /* send it... */
7373   S (mp);
7374
7375   /* Wait for a reply, return good/bad news  */
7376   W (ret);
7377   return ret;
7378 }
7379
7380 static int
7381 api_reset_vrf (vat_main_t * vam)
7382 {
7383   unformat_input_t *i = vam->input;
7384   vl_api_reset_vrf_t *mp;
7385   u32 vrf_id = 0;
7386   u8 is_ipv6 = 0;
7387   u8 vrf_id_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         vrf_id_set = 1;
7394       else if (unformat (i, "ipv6"))
7395         is_ipv6 = 1;
7396       else
7397         {
7398           clib_warning ("parse error '%U'", format_unformat_error, i);
7399           return -99;
7400         }
7401     }
7402
7403   if (vrf_id_set == 0)
7404     {
7405       errmsg ("missing vrf id");
7406       return -99;
7407     }
7408
7409   M (RESET_VRF, mp);
7410
7411   mp->vrf_id = ntohl (vrf_id);
7412   mp->is_ipv6 = is_ipv6;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_create_vlan_subif (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_create_vlan_subif_t *mp;
7424   u32 sw_if_index;
7425   u8 sw_if_index_set = 0;
7426   u32 vlan_id;
7427   u8 vlan_id_set = 0;
7428   int ret;
7429
7430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7431     {
7432       if (unformat (i, "sw_if_index %d", &sw_if_index))
7433         sw_if_index_set = 1;
7434       else
7435         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7436         sw_if_index_set = 1;
7437       else if (unformat (i, "vlan %d", &vlan_id))
7438         vlan_id_set = 1;
7439       else
7440         {
7441           clib_warning ("parse error '%U'", format_unformat_error, i);
7442           return -99;
7443         }
7444     }
7445
7446   if (sw_if_index_set == 0)
7447     {
7448       errmsg ("missing interface name or sw_if_index");
7449       return -99;
7450     }
7451
7452   if (vlan_id_set == 0)
7453     {
7454       errmsg ("missing vlan_id");
7455       return -99;
7456     }
7457   M (CREATE_VLAN_SUBIF, mp);
7458
7459   mp->sw_if_index = ntohl (sw_if_index);
7460   mp->vlan_id = ntohl (vlan_id);
7461
7462   S (mp);
7463   W (ret);
7464   return ret;
7465 }
7466
7467 #define foreach_create_subif_bit                \
7468 _(no_tags)                                      \
7469 _(one_tag)                                      \
7470 _(two_tags)                                     \
7471 _(dot1ad)                                       \
7472 _(exact_match)                                  \
7473 _(default_sub)                                  \
7474 _(outer_vlan_id_any)                            \
7475 _(inner_vlan_id_any)
7476
7477 static int
7478 api_create_subif (vat_main_t * vam)
7479 {
7480   unformat_input_t *i = vam->input;
7481   vl_api_create_subif_t *mp;
7482   u32 sw_if_index;
7483   u8 sw_if_index_set = 0;
7484   u32 sub_id;
7485   u8 sub_id_set = 0;
7486   u32 no_tags = 0;
7487   u32 one_tag = 0;
7488   u32 two_tags = 0;
7489   u32 dot1ad = 0;
7490   u32 exact_match = 0;
7491   u32 default_sub = 0;
7492   u32 outer_vlan_id_any = 0;
7493   u32 inner_vlan_id_any = 0;
7494   u32 tmp;
7495   u16 outer_vlan_id = 0;
7496   u16 inner_vlan_id = 0;
7497   int ret;
7498
7499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (i, "sw_if_index %d", &sw_if_index))
7502         sw_if_index_set = 1;
7503       else
7504         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7505         sw_if_index_set = 1;
7506       else if (unformat (i, "sub_id %d", &sub_id))
7507         sub_id_set = 1;
7508       else if (unformat (i, "outer_vlan_id %d", &tmp))
7509         outer_vlan_id = tmp;
7510       else if (unformat (i, "inner_vlan_id %d", &tmp))
7511         inner_vlan_id = tmp;
7512
7513 #define _(a) else if (unformat (i, #a)) a = 1 ;
7514       foreach_create_subif_bit
7515 #undef _
7516         else
7517         {
7518           clib_warning ("parse error '%U'", format_unformat_error, i);
7519           return -99;
7520         }
7521     }
7522
7523   if (sw_if_index_set == 0)
7524     {
7525       errmsg ("missing interface name or sw_if_index");
7526       return -99;
7527     }
7528
7529   if (sub_id_set == 0)
7530     {
7531       errmsg ("missing sub_id");
7532       return -99;
7533     }
7534   M (CREATE_SUBIF, mp);
7535
7536   mp->sw_if_index = ntohl (sw_if_index);
7537   mp->sub_id = ntohl (sub_id);
7538
7539 #define _(a) mp->a = a;
7540   foreach_create_subif_bit;
7541 #undef _
7542
7543   mp->outer_vlan_id = ntohs (outer_vlan_id);
7544   mp->inner_vlan_id = ntohs (inner_vlan_id);
7545
7546   S (mp);
7547   W (ret);
7548   return ret;
7549 }
7550
7551 static int
7552 api_oam_add_del (vat_main_t * vam)
7553 {
7554   unformat_input_t *i = vam->input;
7555   vl_api_oam_add_del_t *mp;
7556   u32 vrf_id = 0;
7557   u8 is_add = 1;
7558   ip4_address_t src, dst;
7559   u8 src_set = 0;
7560   u8 dst_set = 0;
7561   int ret;
7562
7563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7564     {
7565       if (unformat (i, "vrf %d", &vrf_id))
7566         ;
7567       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7568         src_set = 1;
7569       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7570         dst_set = 1;
7571       else if (unformat (i, "del"))
7572         is_add = 0;
7573       else
7574         {
7575           clib_warning ("parse error '%U'", format_unformat_error, i);
7576           return -99;
7577         }
7578     }
7579
7580   if (src_set == 0)
7581     {
7582       errmsg ("missing src addr");
7583       return -99;
7584     }
7585
7586   if (dst_set == 0)
7587     {
7588       errmsg ("missing dst addr");
7589       return -99;
7590     }
7591
7592   M (OAM_ADD_DEL, mp);
7593
7594   mp->vrf_id = ntohl (vrf_id);
7595   mp->is_add = is_add;
7596   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7597   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7598
7599   S (mp);
7600   W (ret);
7601   return ret;
7602 }
7603
7604 static int
7605 api_reset_fib (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_reset_fib_t *mp;
7609   u32 vrf_id = 0;
7610   u8 is_ipv6 = 0;
7611   u8 vrf_id_set = 0;
7612
7613   int ret;
7614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7615     {
7616       if (unformat (i, "vrf %d", &vrf_id))
7617         vrf_id_set = 1;
7618       else if (unformat (i, "ipv6"))
7619         is_ipv6 = 1;
7620       else
7621         {
7622           clib_warning ("parse error '%U'", format_unformat_error, i);
7623           return -99;
7624         }
7625     }
7626
7627   if (vrf_id_set == 0)
7628     {
7629       errmsg ("missing vrf id");
7630       return -99;
7631     }
7632
7633   M (RESET_FIB, mp);
7634
7635   mp->vrf_id = ntohl (vrf_id);
7636   mp->is_ipv6 = is_ipv6;
7637
7638   S (mp);
7639   W (ret);
7640   return ret;
7641 }
7642
7643 static int
7644 api_dhcp_proxy_config (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_dhcp_proxy_config_t *mp;
7648   u32 rx_vrf_id = 0;
7649   u32 server_vrf_id = 0;
7650   u8 is_add = 1;
7651   u8 v4_address_set = 0;
7652   u8 v6_address_set = 0;
7653   ip4_address_t v4address;
7654   ip6_address_t v6address;
7655   u8 v4_src_address_set = 0;
7656   u8 v6_src_address_set = 0;
7657   ip4_address_t v4srcaddress;
7658   ip6_address_t v6srcaddress;
7659   int ret;
7660
7661   /* Parse args required to build the message */
7662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7663     {
7664       if (unformat (i, "del"))
7665         is_add = 0;
7666       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7667         ;
7668       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7669         ;
7670       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7671         v4_address_set = 1;
7672       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7673         v6_address_set = 1;
7674       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7675         v4_src_address_set = 1;
7676       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7677         v6_src_address_set = 1;
7678       else
7679         break;
7680     }
7681
7682   if (v4_address_set && v6_address_set)
7683     {
7684       errmsg ("both v4 and v6 server addresses set");
7685       return -99;
7686     }
7687   if (!v4_address_set && !v6_address_set)
7688     {
7689       errmsg ("no server addresses set");
7690       return -99;
7691     }
7692
7693   if (v4_src_address_set && v6_src_address_set)
7694     {
7695       errmsg ("both v4 and v6  src addresses set");
7696       return -99;
7697     }
7698   if (!v4_src_address_set && !v6_src_address_set)
7699     {
7700       errmsg ("no src addresses set");
7701       return -99;
7702     }
7703
7704   if (!(v4_src_address_set && v4_address_set) &&
7705       !(v6_src_address_set && v6_address_set))
7706     {
7707       errmsg ("no matching server and src addresses set");
7708       return -99;
7709     }
7710
7711   /* Construct the API message */
7712   M (DHCP_PROXY_CONFIG, mp);
7713
7714   mp->is_add = is_add;
7715   mp->rx_vrf_id = ntohl (rx_vrf_id);
7716   mp->server_vrf_id = ntohl (server_vrf_id);
7717   if (v6_address_set)
7718     {
7719       mp->is_ipv6 = 1;
7720       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7721       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7722     }
7723   else
7724     {
7725       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7726       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7727     }
7728
7729   /* send it... */
7730   S (mp);
7731
7732   /* Wait for a reply, return good/bad news  */
7733   W (ret);
7734   return ret;
7735 }
7736
7737 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7738 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7739
7740 static void
7741 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7742 {
7743   vat_main_t *vam = &vat_main;
7744
7745   if (mp->is_ipv6)
7746     print (vam->ofp,
7747            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7748            ntohl (mp->rx_vrf_id),
7749            ntohl (mp->server_vrf_id),
7750            format_ip6_address, mp->dhcp_server,
7751            format_ip6_address, mp->dhcp_src_address,
7752            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7753   else
7754     print (vam->ofp,
7755            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7756            ntohl (mp->rx_vrf_id),
7757            ntohl (mp->server_vrf_id),
7758            format_ip4_address, mp->dhcp_server,
7759            format_ip4_address, mp->dhcp_src_address,
7760            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7761 }
7762
7763 static void vl_api_dhcp_proxy_details_t_handler_json
7764   (vl_api_dhcp_proxy_details_t * mp)
7765 {
7766   vat_main_t *vam = &vat_main;
7767   vat_json_node_t *node = NULL;
7768   struct in_addr ip4;
7769   struct in6_addr ip6;
7770
7771   if (VAT_JSON_ARRAY != vam->json_tree.type)
7772     {
7773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7774       vat_json_init_array (&vam->json_tree);
7775     }
7776   node = vat_json_array_add (&vam->json_tree);
7777
7778   vat_json_init_object (node);
7779   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7780   vat_json_object_add_uint (node, "server-table-id",
7781                             ntohl (mp->server_vrf_id));
7782   if (mp->is_ipv6)
7783     {
7784       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7785       vat_json_object_add_ip6 (node, "server_address", ip6);
7786       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7787       vat_json_object_add_ip6 (node, "src_address", ip6);
7788     }
7789   else
7790     {
7791       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7792       vat_json_object_add_ip4 (node, "server_address", ip4);
7793       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7794       vat_json_object_add_ip4 (node, "src_address", ip4);
7795     }
7796   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7797   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7798 }
7799
7800 static int
7801 api_dhcp_proxy_dump (vat_main_t * vam)
7802 {
7803   unformat_input_t *i = vam->input;
7804   vl_api_control_ping_t *mp_ping;
7805   vl_api_dhcp_proxy_dump_t *mp;
7806   u8 is_ipv6 = 0;
7807   int ret;
7808
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "ipv6"))
7812         is_ipv6 = 1;
7813       else
7814         {
7815           clib_warning ("parse error '%U'", format_unformat_error, i);
7816           return -99;
7817         }
7818     }
7819
7820   M (DHCP_PROXY_DUMP, mp);
7821
7822   mp->is_ip6 = is_ipv6;
7823   S (mp);
7824
7825   /* Use a control ping for synchronization */
7826   M (CONTROL_PING, mp_ping);
7827   S (mp_ping);
7828
7829   W (ret);
7830   return ret;
7831 }
7832
7833 static int
7834 api_dhcp_proxy_set_vss (vat_main_t * vam)
7835 {
7836   unformat_input_t *i = vam->input;
7837   vl_api_dhcp_proxy_set_vss_t *mp;
7838   u8 is_ipv6 = 0;
7839   u8 is_add = 1;
7840   u32 tbl_id;
7841   u8 tbl_id_set = 0;
7842   u32 oui;
7843   u8 oui_set = 0;
7844   u32 fib_id;
7845   u8 fib_id_set = 0;
7846   int ret;
7847
7848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7849     {
7850       if (unformat (i, "tbl_id %d", &tbl_id))
7851         tbl_id_set = 1;
7852       if (unformat (i, "fib_id %d", &fib_id))
7853         fib_id_set = 1;
7854       if (unformat (i, "oui %d", &oui))
7855         oui_set = 1;
7856       else if (unformat (i, "ipv6"))
7857         is_ipv6 = 1;
7858       else if (unformat (i, "del"))
7859         is_add = 0;
7860       else
7861         {
7862           clib_warning ("parse error '%U'", format_unformat_error, i);
7863           return -99;
7864         }
7865     }
7866
7867   if (tbl_id_set == 0)
7868     {
7869       errmsg ("missing tbl id");
7870       return -99;
7871     }
7872
7873   if (fib_id_set == 0)
7874     {
7875       errmsg ("missing fib id");
7876       return -99;
7877     }
7878   if (oui_set == 0)
7879     {
7880       errmsg ("missing oui");
7881       return -99;
7882     }
7883
7884   M (DHCP_PROXY_SET_VSS, mp);
7885   mp->tbl_id = ntohl (tbl_id);
7886   mp->fib_id = ntohl (fib_id);
7887   mp->oui = ntohl (oui);
7888   mp->is_ipv6 = is_ipv6;
7889   mp->is_add = is_add;
7890
7891   S (mp);
7892   W (ret);
7893   return ret;
7894 }
7895
7896 static int
7897 api_dhcp_client_config (vat_main_t * vam)
7898 {
7899   unformat_input_t *i = vam->input;
7900   vl_api_dhcp_client_config_t *mp;
7901   u32 sw_if_index;
7902   u8 sw_if_index_set = 0;
7903   u8 is_add = 1;
7904   u8 *hostname = 0;
7905   u8 disable_event = 0;
7906   int ret;
7907
7908   /* Parse args required to build the message */
7909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7910     {
7911       if (unformat (i, "del"))
7912         is_add = 0;
7913       else
7914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7915         sw_if_index_set = 1;
7916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917         sw_if_index_set = 1;
7918       else if (unformat (i, "hostname %s", &hostname))
7919         ;
7920       else if (unformat (i, "disable_event"))
7921         disable_event = 1;
7922       else
7923         break;
7924     }
7925
7926   if (sw_if_index_set == 0)
7927     {
7928       errmsg ("missing interface name or sw_if_index");
7929       return -99;
7930     }
7931
7932   if (vec_len (hostname) > 63)
7933     {
7934       errmsg ("hostname too long");
7935     }
7936   vec_add1 (hostname, 0);
7937
7938   /* Construct the API message */
7939   M (DHCP_CLIENT_CONFIG, mp);
7940
7941   mp->sw_if_index = ntohl (sw_if_index);
7942   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7943   vec_free (hostname);
7944   mp->is_add = is_add;
7945   mp->want_dhcp_event = disable_event ? 0 : 1;
7946   mp->pid = getpid ();
7947
7948   /* send it... */
7949   S (mp);
7950
7951   /* Wait for a reply, return good/bad news  */
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_set_ip_flow_hash (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_set_ip_flow_hash_t *mp;
7961   u32 vrf_id = 0;
7962   u8 is_ipv6 = 0;
7963   u8 vrf_id_set = 0;
7964   u8 src = 0;
7965   u8 dst = 0;
7966   u8 sport = 0;
7967   u8 dport = 0;
7968   u8 proto = 0;
7969   u8 reverse = 0;
7970   int ret;
7971
7972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7973     {
7974       if (unformat (i, "vrf %d", &vrf_id))
7975         vrf_id_set = 1;
7976       else if (unformat (i, "ipv6"))
7977         is_ipv6 = 1;
7978       else if (unformat (i, "src"))
7979         src = 1;
7980       else if (unformat (i, "dst"))
7981         dst = 1;
7982       else if (unformat (i, "sport"))
7983         sport = 1;
7984       else if (unformat (i, "dport"))
7985         dport = 1;
7986       else if (unformat (i, "proto"))
7987         proto = 1;
7988       else if (unformat (i, "reverse"))
7989         reverse = 1;
7990
7991       else
7992         {
7993           clib_warning ("parse error '%U'", format_unformat_error, i);
7994           return -99;
7995         }
7996     }
7997
7998   if (vrf_id_set == 0)
7999     {
8000       errmsg ("missing vrf id");
8001       return -99;
8002     }
8003
8004   M (SET_IP_FLOW_HASH, mp);
8005   mp->src = src;
8006   mp->dst = dst;
8007   mp->sport = sport;
8008   mp->dport = dport;
8009   mp->proto = proto;
8010   mp->reverse = reverse;
8011   mp->vrf_id = ntohl (vrf_id);
8012   mp->is_ipv6 = is_ipv6;
8013
8014   S (mp);
8015   W (ret);
8016   return ret;
8017 }
8018
8019 static int
8020 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8021 {
8022   unformat_input_t *i = vam->input;
8023   vl_api_sw_interface_ip6_enable_disable_t *mp;
8024   u32 sw_if_index;
8025   u8 sw_if_index_set = 0;
8026   u8 enable = 0;
8027   int ret;
8028
8029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8030     {
8031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8032         sw_if_index_set = 1;
8033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8034         sw_if_index_set = 1;
8035       else if (unformat (i, "enable"))
8036         enable = 1;
8037       else if (unformat (i, "disable"))
8038         enable = 0;
8039       else
8040         {
8041           clib_warning ("parse error '%U'", format_unformat_error, i);
8042           return -99;
8043         }
8044     }
8045
8046   if (sw_if_index_set == 0)
8047     {
8048       errmsg ("missing interface name or sw_if_index");
8049       return -99;
8050     }
8051
8052   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8053
8054   mp->sw_if_index = ntohl (sw_if_index);
8055   mp->enable = enable;
8056
8057   S (mp);
8058   W (ret);
8059   return ret;
8060 }
8061
8062 static int
8063 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8064 {
8065   unformat_input_t *i = vam->input;
8066   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8067   u32 sw_if_index;
8068   u8 sw_if_index_set = 0;
8069   u8 v6_address_set = 0;
8070   ip6_address_t v6address;
8071   int ret;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8077         sw_if_index_set = 1;
8078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8079         sw_if_index_set = 1;
8080       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8081         v6_address_set = 1;
8082       else
8083         break;
8084     }
8085
8086   if (sw_if_index_set == 0)
8087     {
8088       errmsg ("missing interface name or sw_if_index");
8089       return -99;
8090     }
8091   if (!v6_address_set)
8092     {
8093       errmsg ("no address set");
8094       return -99;
8095     }
8096
8097   /* Construct the API message */
8098   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8099
8100   mp->sw_if_index = ntohl (sw_if_index);
8101   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8102
8103   /* send it... */
8104   S (mp);
8105
8106   /* Wait for a reply, return good/bad news  */
8107   W (ret);
8108   return ret;
8109 }
8110
8111
8112 static int
8113 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8114 {
8115   unformat_input_t *i = vam->input;
8116   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8117   u32 sw_if_index;
8118   u8 sw_if_index_set = 0;
8119   u32 address_length = 0;
8120   u8 v6_address_set = 0;
8121   ip6_address_t v6address;
8122   u8 use_default = 0;
8123   u8 no_advertise = 0;
8124   u8 off_link = 0;
8125   u8 no_autoconfig = 0;
8126   u8 no_onlink = 0;
8127   u8 is_no = 0;
8128   u32 val_lifetime = 0;
8129   u32 pref_lifetime = 0;
8130   int ret;
8131
8132   /* Parse args required to build the message */
8133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8134     {
8135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8136         sw_if_index_set = 1;
8137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8138         sw_if_index_set = 1;
8139       else if (unformat (i, "%U/%d",
8140                          unformat_ip6_address, &v6address, &address_length))
8141         v6_address_set = 1;
8142       else if (unformat (i, "val_life %d", &val_lifetime))
8143         ;
8144       else if (unformat (i, "pref_life %d", &pref_lifetime))
8145         ;
8146       else if (unformat (i, "def"))
8147         use_default = 1;
8148       else if (unformat (i, "noadv"))
8149         no_advertise = 1;
8150       else if (unformat (i, "offl"))
8151         off_link = 1;
8152       else if (unformat (i, "noauto"))
8153         no_autoconfig = 1;
8154       else if (unformat (i, "nolink"))
8155         no_onlink = 1;
8156       else if (unformat (i, "isno"))
8157         is_no = 1;
8158       else
8159         {
8160           clib_warning ("parse error '%U'", format_unformat_error, i);
8161           return -99;
8162         }
8163     }
8164
8165   if (sw_if_index_set == 0)
8166     {
8167       errmsg ("missing interface name or sw_if_index");
8168       return -99;
8169     }
8170   if (!v6_address_set)
8171     {
8172       errmsg ("no address set");
8173       return -99;
8174     }
8175
8176   /* Construct the API message */
8177   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8178
8179   mp->sw_if_index = ntohl (sw_if_index);
8180   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8181   mp->address_length = address_length;
8182   mp->use_default = use_default;
8183   mp->no_advertise = no_advertise;
8184   mp->off_link = off_link;
8185   mp->no_autoconfig = no_autoconfig;
8186   mp->no_onlink = no_onlink;
8187   mp->is_no = is_no;
8188   mp->val_lifetime = ntohl (val_lifetime);
8189   mp->pref_lifetime = ntohl (pref_lifetime);
8190
8191   /* send it... */
8192   S (mp);
8193
8194   /* Wait for a reply, return good/bad news  */
8195   W (ret);
8196   return ret;
8197 }
8198
8199 static int
8200 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8201 {
8202   unformat_input_t *i = vam->input;
8203   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8204   u32 sw_if_index;
8205   u8 sw_if_index_set = 0;
8206   u8 suppress = 0;
8207   u8 managed = 0;
8208   u8 other = 0;
8209   u8 ll_option = 0;
8210   u8 send_unicast = 0;
8211   u8 cease = 0;
8212   u8 is_no = 0;
8213   u8 default_router = 0;
8214   u32 max_interval = 0;
8215   u32 min_interval = 0;
8216   u32 lifetime = 0;
8217   u32 initial_count = 0;
8218   u32 initial_interval = 0;
8219   int ret;
8220
8221
8222   /* Parse args required to build the message */
8223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8226         sw_if_index_set = 1;
8227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8228         sw_if_index_set = 1;
8229       else if (unformat (i, "maxint %d", &max_interval))
8230         ;
8231       else if (unformat (i, "minint %d", &min_interval))
8232         ;
8233       else if (unformat (i, "life %d", &lifetime))
8234         ;
8235       else if (unformat (i, "count %d", &initial_count))
8236         ;
8237       else if (unformat (i, "interval %d", &initial_interval))
8238         ;
8239       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8240         suppress = 1;
8241       else if (unformat (i, "managed"))
8242         managed = 1;
8243       else if (unformat (i, "other"))
8244         other = 1;
8245       else if (unformat (i, "ll"))
8246         ll_option = 1;
8247       else if (unformat (i, "send"))
8248         send_unicast = 1;
8249       else if (unformat (i, "cease"))
8250         cease = 1;
8251       else if (unformat (i, "isno"))
8252         is_no = 1;
8253       else if (unformat (i, "def"))
8254         default_router = 1;
8255       else
8256         {
8257           clib_warning ("parse error '%U'", format_unformat_error, i);
8258           return -99;
8259         }
8260     }
8261
8262   if (sw_if_index_set == 0)
8263     {
8264       errmsg ("missing interface name or sw_if_index");
8265       return -99;
8266     }
8267
8268   /* Construct the API message */
8269   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8270
8271   mp->sw_if_index = ntohl (sw_if_index);
8272   mp->max_interval = ntohl (max_interval);
8273   mp->min_interval = ntohl (min_interval);
8274   mp->lifetime = ntohl (lifetime);
8275   mp->initial_count = ntohl (initial_count);
8276   mp->initial_interval = ntohl (initial_interval);
8277   mp->suppress = suppress;
8278   mp->managed = managed;
8279   mp->other = other;
8280   mp->ll_option = ll_option;
8281   mp->send_unicast = send_unicast;
8282   mp->cease = cease;
8283   mp->is_no = is_no;
8284   mp->default_router = default_router;
8285
8286   /* send it... */
8287   S (mp);
8288
8289   /* Wait for a reply, return good/bad news  */
8290   W (ret);
8291   return ret;
8292 }
8293
8294 static int
8295 api_set_arp_neighbor_limit (vat_main_t * vam)
8296 {
8297   unformat_input_t *i = vam->input;
8298   vl_api_set_arp_neighbor_limit_t *mp;
8299   u32 arp_nbr_limit;
8300   u8 limit_set = 0;
8301   u8 is_ipv6 = 0;
8302   int ret;
8303
8304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8305     {
8306       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8307         limit_set = 1;
8308       else if (unformat (i, "ipv6"))
8309         is_ipv6 = 1;
8310       else
8311         {
8312           clib_warning ("parse error '%U'", format_unformat_error, i);
8313           return -99;
8314         }
8315     }
8316
8317   if (limit_set == 0)
8318     {
8319       errmsg ("missing limit value");
8320       return -99;
8321     }
8322
8323   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8324
8325   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8326   mp->is_ipv6 = is_ipv6;
8327
8328   S (mp);
8329   W (ret);
8330   return ret;
8331 }
8332
8333 static int
8334 api_l2_patch_add_del (vat_main_t * vam)
8335 {
8336   unformat_input_t *i = vam->input;
8337   vl_api_l2_patch_add_del_t *mp;
8338   u32 rx_sw_if_index;
8339   u8 rx_sw_if_index_set = 0;
8340   u32 tx_sw_if_index;
8341   u8 tx_sw_if_index_set = 0;
8342   u8 is_add = 1;
8343   int ret;
8344
8345   /* Parse args required to build the message */
8346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347     {
8348       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8349         rx_sw_if_index_set = 1;
8350       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8351         tx_sw_if_index_set = 1;
8352       else if (unformat (i, "rx"))
8353         {
8354           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8355             {
8356               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8357                             &rx_sw_if_index))
8358                 rx_sw_if_index_set = 1;
8359             }
8360           else
8361             break;
8362         }
8363       else if (unformat (i, "tx"))
8364         {
8365           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8366             {
8367               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8368                             &tx_sw_if_index))
8369                 tx_sw_if_index_set = 1;
8370             }
8371           else
8372             break;
8373         }
8374       else if (unformat (i, "del"))
8375         is_add = 0;
8376       else
8377         break;
8378     }
8379
8380   if (rx_sw_if_index_set == 0)
8381     {
8382       errmsg ("missing rx interface name or rx_sw_if_index");
8383       return -99;
8384     }
8385
8386   if (tx_sw_if_index_set == 0)
8387     {
8388       errmsg ("missing tx interface name or tx_sw_if_index");
8389       return -99;
8390     }
8391
8392   M (L2_PATCH_ADD_DEL, mp);
8393
8394   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8395   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8396   mp->is_add = is_add;
8397
8398   S (mp);
8399   W (ret);
8400   return ret;
8401 }
8402
8403 static int
8404 api_ioam_enable (vat_main_t * vam)
8405 {
8406   unformat_input_t *input = vam->input;
8407   vl_api_ioam_enable_t *mp;
8408   u32 id = 0;
8409   int has_trace_option = 0;
8410   int has_pot_option = 0;
8411   int has_seqno_option = 0;
8412   int has_analyse_option = 0;
8413   int ret;
8414
8415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8416     {
8417       if (unformat (input, "trace"))
8418         has_trace_option = 1;
8419       else if (unformat (input, "pot"))
8420         has_pot_option = 1;
8421       else if (unformat (input, "seqno"))
8422         has_seqno_option = 1;
8423       else if (unformat (input, "analyse"))
8424         has_analyse_option = 1;
8425       else
8426         break;
8427     }
8428   M (IOAM_ENABLE, mp);
8429   mp->id = htons (id);
8430   mp->seqno = has_seqno_option;
8431   mp->analyse = has_analyse_option;
8432   mp->pot_enable = has_pot_option;
8433   mp->trace_enable = has_trace_option;
8434
8435   S (mp);
8436   W (ret);
8437   return ret;
8438 }
8439
8440
8441 static int
8442 api_ioam_disable (vat_main_t * vam)
8443 {
8444   vl_api_ioam_disable_t *mp;
8445   int ret;
8446
8447   M (IOAM_DISABLE, mp);
8448   S (mp);
8449   W (ret);
8450   return ret;
8451 }
8452
8453 static int
8454 api_sr_tunnel_add_del (vat_main_t * vam)
8455 {
8456   unformat_input_t *i = vam->input;
8457   vl_api_sr_tunnel_add_del_t *mp;
8458   int is_del = 0;
8459   int pl_index;
8460   ip6_address_t src_address;
8461   int src_address_set = 0;
8462   ip6_address_t dst_address;
8463   u32 dst_mask_width;
8464   int dst_address_set = 0;
8465   u16 flags = 0;
8466   u32 rx_table_id = 0;
8467   u32 tx_table_id = 0;
8468   ip6_address_t *segments = 0;
8469   ip6_address_t *this_seg;
8470   ip6_address_t *tags = 0;
8471   ip6_address_t *this_tag;
8472   ip6_address_t next_address, tag;
8473   u8 *name = 0;
8474   u8 *policy_name = 0;
8475   int ret;
8476
8477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8478     {
8479       if (unformat (i, "del"))
8480         is_del = 1;
8481       else if (unformat (i, "name %s", &name))
8482         ;
8483       else if (unformat (i, "policy %s", &policy_name))
8484         ;
8485       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8486         ;
8487       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8488         ;
8489       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8490         src_address_set = 1;
8491       else if (unformat (i, "dst %U/%d",
8492                          unformat_ip6_address, &dst_address, &dst_mask_width))
8493         dst_address_set = 1;
8494       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8495         {
8496           vec_add2 (segments, this_seg, 1);
8497           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8498                        sizeof (*this_seg));
8499         }
8500       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8501         {
8502           vec_add2 (tags, this_tag, 1);
8503           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8504         }
8505       else if (unformat (i, "clean"))
8506         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8507       else if (unformat (i, "protected"))
8508         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8509       else if (unformat (i, "InPE %d", &pl_index))
8510         {
8511           if (pl_index <= 0 || pl_index > 4)
8512             {
8513             pl_index_range_error:
8514               errmsg ("pl index %d out of range", pl_index);
8515               return -99;
8516             }
8517           flags |=
8518             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8519         }
8520       else if (unformat (i, "EgPE %d", &pl_index))
8521         {
8522           if (pl_index <= 0 || pl_index > 4)
8523             goto pl_index_range_error;
8524           flags |=
8525             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8526         }
8527       else if (unformat (i, "OrgSrc %d", &pl_index))
8528         {
8529           if (pl_index <= 0 || pl_index > 4)
8530             goto pl_index_range_error;
8531           flags |=
8532             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8533         }
8534       else
8535         break;
8536     }
8537
8538   if (!src_address_set)
8539     {
8540       errmsg ("src address required");
8541       return -99;
8542     }
8543
8544   if (!dst_address_set)
8545     {
8546       errmsg ("dst address required");
8547       return -99;
8548     }
8549
8550   if (!segments)
8551     {
8552       errmsg ("at least one sr segment required");
8553       return -99;
8554     }
8555
8556   M2 (SR_TUNNEL_ADD_DEL, mp,
8557       vec_len (segments) * sizeof (ip6_address_t)
8558       + vec_len (tags) * sizeof (ip6_address_t));
8559
8560   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8561   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8562   mp->dst_mask_width = dst_mask_width;
8563   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8564   mp->n_segments = vec_len (segments);
8565   mp->n_tags = vec_len (tags);
8566   mp->is_add = is_del == 0;
8567   clib_memcpy (mp->segs_and_tags, segments,
8568                vec_len (segments) * sizeof (ip6_address_t));
8569   clib_memcpy (mp->segs_and_tags +
8570                vec_len (segments) * sizeof (ip6_address_t), tags,
8571                vec_len (tags) * sizeof (ip6_address_t));
8572
8573   mp->outer_vrf_id = ntohl (rx_table_id);
8574   mp->inner_vrf_id = ntohl (tx_table_id);
8575   memcpy (mp->name, name, vec_len (name));
8576   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8577
8578   vec_free (segments);
8579   vec_free (tags);
8580
8581   S (mp);
8582   W (ret);
8583   return ret;
8584 }
8585
8586 static int
8587 api_sr_policy_add_del (vat_main_t * vam)
8588 {
8589   unformat_input_t *input = vam->input;
8590   vl_api_sr_policy_add_del_t *mp;
8591   int is_del = 0;
8592   u8 *name = 0;
8593   u8 *tunnel_name = 0;
8594   u8 **tunnel_names = 0;
8595
8596   int name_set = 0;
8597   int tunnel_set = 0;
8598   int j = 0;
8599   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8600   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8601   int ret;
8602
8603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8604     {
8605       if (unformat (input, "del"))
8606         is_del = 1;
8607       else if (unformat (input, "name %s", &name))
8608         name_set = 1;
8609       else if (unformat (input, "tunnel %s", &tunnel_name))
8610         {
8611           if (tunnel_name)
8612             {
8613               vec_add1 (tunnel_names, tunnel_name);
8614               /* For serializer:
8615                  - length = #bytes to store in serial vector
8616                  - +1 = byte to store that length
8617                */
8618               tunnel_names_length += (vec_len (tunnel_name) + 1);
8619               tunnel_set = 1;
8620               tunnel_name = 0;
8621             }
8622         }
8623       else
8624         break;
8625     }
8626
8627   if (!name_set)
8628     {
8629       errmsg ("policy name required");
8630       return -99;
8631     }
8632
8633   if ((!tunnel_set) && (!is_del))
8634     {
8635       errmsg ("tunnel name required");
8636       return -99;
8637     }
8638
8639   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8640
8641
8642
8643   mp->is_add = !is_del;
8644
8645   memcpy (mp->name, name, vec_len (name));
8646   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8647   u8 *serial_orig = 0;
8648   vec_validate (serial_orig, tunnel_names_length);
8649   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8650   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8651
8652   for (j = 0; j < vec_len (tunnel_names); j++)
8653     {
8654       tun_name_len = vec_len (tunnel_names[j]);
8655       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8656       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8657       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8658       serial_orig += tun_name_len;      // Advance past the copy
8659     }
8660   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8661
8662   vec_free (tunnel_names);
8663   vec_free (tunnel_name);
8664
8665   S (mp);
8666   W (ret);
8667   return ret;
8668 }
8669
8670 static int
8671 api_sr_multicast_map_add_del (vat_main_t * vam)
8672 {
8673   unformat_input_t *input = vam->input;
8674   vl_api_sr_multicast_map_add_del_t *mp;
8675   int is_del = 0;
8676   ip6_address_t multicast_address;
8677   u8 *policy_name = 0;
8678   int multicast_address_set = 0;
8679   int ret;
8680
8681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8682     {
8683       if (unformat (input, "del"))
8684         is_del = 1;
8685       else
8686         if (unformat
8687             (input, "address %U", unformat_ip6_address, &multicast_address))
8688         multicast_address_set = 1;
8689       else if (unformat (input, "sr-policy %s", &policy_name))
8690         ;
8691       else
8692         break;
8693     }
8694
8695   if (!is_del && !policy_name)
8696     {
8697       errmsg ("sr-policy name required");
8698       return -99;
8699     }
8700
8701
8702   if (!multicast_address_set)
8703     {
8704       errmsg ("address required");
8705       return -99;
8706     }
8707
8708   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8709
8710   mp->is_add = !is_del;
8711   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8712   clib_memcpy (mp->multicast_address, &multicast_address,
8713                sizeof (mp->multicast_address));
8714
8715
8716   vec_free (policy_name);
8717
8718   S (mp);
8719   W (ret);
8720   return ret;
8721 }
8722
8723
8724 #define foreach_tcp_proto_field                 \
8725 _(src_port)                                     \
8726 _(dst_port)
8727
8728 #define foreach_udp_proto_field                 \
8729 _(src_port)                                     \
8730 _(dst_port)
8731
8732 #define foreach_ip4_proto_field                 \
8733 _(src_address)                                  \
8734 _(dst_address)                                  \
8735 _(tos)                                          \
8736 _(length)                                       \
8737 _(fragment_id)                                  \
8738 _(ttl)                                          \
8739 _(protocol)                                     \
8740 _(checksum)
8741
8742 typedef struct
8743 {
8744   u16 src_port, dst_port;
8745 } tcpudp_header_t;
8746
8747 #if VPP_API_TEST_BUILTIN == 0
8748 uword
8749 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8750 {
8751   u8 **maskp = va_arg (*args, u8 **);
8752   u8 *mask = 0;
8753   u8 found_something = 0;
8754   tcp_header_t *tcp;
8755
8756 #define _(a) u8 a=0;
8757   foreach_tcp_proto_field;
8758 #undef _
8759
8760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8761     {
8762       if (0);
8763 #define _(a) else if (unformat (input, #a)) a=1;
8764       foreach_tcp_proto_field
8765 #undef _
8766         else
8767         break;
8768     }
8769
8770 #define _(a) found_something += a;
8771   foreach_tcp_proto_field;
8772 #undef _
8773
8774   if (found_something == 0)
8775     return 0;
8776
8777   vec_validate (mask, sizeof (*tcp) - 1);
8778
8779   tcp = (tcp_header_t *) mask;
8780
8781 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8782   foreach_tcp_proto_field;
8783 #undef _
8784
8785   *maskp = mask;
8786   return 1;
8787 }
8788
8789 uword
8790 unformat_udp_mask (unformat_input_t * input, va_list * args)
8791 {
8792   u8 **maskp = va_arg (*args, u8 **);
8793   u8 *mask = 0;
8794   u8 found_something = 0;
8795   udp_header_t *udp;
8796
8797 #define _(a) u8 a=0;
8798   foreach_udp_proto_field;
8799 #undef _
8800
8801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8802     {
8803       if (0);
8804 #define _(a) else if (unformat (input, #a)) a=1;
8805       foreach_udp_proto_field
8806 #undef _
8807         else
8808         break;
8809     }
8810
8811 #define _(a) found_something += a;
8812   foreach_udp_proto_field;
8813 #undef _
8814
8815   if (found_something == 0)
8816     return 0;
8817
8818   vec_validate (mask, sizeof (*udp) - 1);
8819
8820   udp = (udp_header_t *) mask;
8821
8822 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8823   foreach_udp_proto_field;
8824 #undef _
8825
8826   *maskp = mask;
8827   return 1;
8828 }
8829
8830 uword
8831 unformat_l4_mask (unformat_input_t * input, va_list * args)
8832 {
8833   u8 **maskp = va_arg (*args, u8 **);
8834   u16 src_port = 0, dst_port = 0;
8835   tcpudp_header_t *tcpudp;
8836
8837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8838     {
8839       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8840         return 1;
8841       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8842         return 1;
8843       else if (unformat (input, "src_port"))
8844         src_port = 0xFFFF;
8845       else if (unformat (input, "dst_port"))
8846         dst_port = 0xFFFF;
8847       else
8848         return 0;
8849     }
8850
8851   if (!src_port && !dst_port)
8852     return 0;
8853
8854   u8 *mask = 0;
8855   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8856
8857   tcpudp = (tcpudp_header_t *) mask;
8858   tcpudp->src_port = src_port;
8859   tcpudp->dst_port = dst_port;
8860
8861   *maskp = mask;
8862
8863   return 1;
8864 }
8865
8866 uword
8867 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8868 {
8869   u8 **maskp = va_arg (*args, u8 **);
8870   u8 *mask = 0;
8871   u8 found_something = 0;
8872   ip4_header_t *ip;
8873
8874 #define _(a) u8 a=0;
8875   foreach_ip4_proto_field;
8876 #undef _
8877   u8 version = 0;
8878   u8 hdr_length = 0;
8879
8880
8881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8882     {
8883       if (unformat (input, "version"))
8884         version = 1;
8885       else if (unformat (input, "hdr_length"))
8886         hdr_length = 1;
8887       else if (unformat (input, "src"))
8888         src_address = 1;
8889       else if (unformat (input, "dst"))
8890         dst_address = 1;
8891       else if (unformat (input, "proto"))
8892         protocol = 1;
8893
8894 #define _(a) else if (unformat (input, #a)) a=1;
8895       foreach_ip4_proto_field
8896 #undef _
8897         else
8898         break;
8899     }
8900
8901 #define _(a) found_something += a;
8902   foreach_ip4_proto_field;
8903 #undef _
8904
8905   if (found_something == 0)
8906     return 0;
8907
8908   vec_validate (mask, sizeof (*ip) - 1);
8909
8910   ip = (ip4_header_t *) mask;
8911
8912 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8913   foreach_ip4_proto_field;
8914 #undef _
8915
8916   ip->ip_version_and_header_length = 0;
8917
8918   if (version)
8919     ip->ip_version_and_header_length |= 0xF0;
8920
8921   if (hdr_length)
8922     ip->ip_version_and_header_length |= 0x0F;
8923
8924   *maskp = mask;
8925   return 1;
8926 }
8927
8928 #define foreach_ip6_proto_field                 \
8929 _(src_address)                                  \
8930 _(dst_address)                                  \
8931 _(payload_length)                               \
8932 _(hop_limit)                                    \
8933 _(protocol)
8934
8935 uword
8936 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8937 {
8938   u8 **maskp = va_arg (*args, u8 **);
8939   u8 *mask = 0;
8940   u8 found_something = 0;
8941   ip6_header_t *ip;
8942   u32 ip_version_traffic_class_and_flow_label;
8943
8944 #define _(a) u8 a=0;
8945   foreach_ip6_proto_field;
8946 #undef _
8947   u8 version = 0;
8948   u8 traffic_class = 0;
8949   u8 flow_label = 0;
8950
8951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8952     {
8953       if (unformat (input, "version"))
8954         version = 1;
8955       else if (unformat (input, "traffic-class"))
8956         traffic_class = 1;
8957       else if (unformat (input, "flow-label"))
8958         flow_label = 1;
8959       else if (unformat (input, "src"))
8960         src_address = 1;
8961       else if (unformat (input, "dst"))
8962         dst_address = 1;
8963       else if (unformat (input, "proto"))
8964         protocol = 1;
8965
8966 #define _(a) else if (unformat (input, #a)) a=1;
8967       foreach_ip6_proto_field
8968 #undef _
8969         else
8970         break;
8971     }
8972
8973 #define _(a) found_something += a;
8974   foreach_ip6_proto_field;
8975 #undef _
8976
8977   if (found_something == 0)
8978     return 0;
8979
8980   vec_validate (mask, sizeof (*ip) - 1);
8981
8982   ip = (ip6_header_t *) mask;
8983
8984 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8985   foreach_ip6_proto_field;
8986 #undef _
8987
8988   ip_version_traffic_class_and_flow_label = 0;
8989
8990   if (version)
8991     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8992
8993   if (traffic_class)
8994     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8995
8996   if (flow_label)
8997     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8998
8999   ip->ip_version_traffic_class_and_flow_label =
9000     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9001
9002   *maskp = mask;
9003   return 1;
9004 }
9005
9006 uword
9007 unformat_l3_mask (unformat_input_t * input, va_list * args)
9008 {
9009   u8 **maskp = va_arg (*args, u8 **);
9010
9011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9012     {
9013       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9014         return 1;
9015       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9016         return 1;
9017       else
9018         break;
9019     }
9020   return 0;
9021 }
9022
9023 uword
9024 unformat_l2_mask (unformat_input_t * input, va_list * args)
9025 {
9026   u8 **maskp = va_arg (*args, u8 **);
9027   u8 *mask = 0;
9028   u8 src = 0;
9029   u8 dst = 0;
9030   u8 proto = 0;
9031   u8 tag1 = 0;
9032   u8 tag2 = 0;
9033   u8 ignore_tag1 = 0;
9034   u8 ignore_tag2 = 0;
9035   u8 cos1 = 0;
9036   u8 cos2 = 0;
9037   u8 dot1q = 0;
9038   u8 dot1ad = 0;
9039   int len = 14;
9040
9041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (input, "src"))
9044         src = 1;
9045       else if (unformat (input, "dst"))
9046         dst = 1;
9047       else if (unformat (input, "proto"))
9048         proto = 1;
9049       else if (unformat (input, "tag1"))
9050         tag1 = 1;
9051       else if (unformat (input, "tag2"))
9052         tag2 = 1;
9053       else if (unformat (input, "ignore-tag1"))
9054         ignore_tag1 = 1;
9055       else if (unformat (input, "ignore-tag2"))
9056         ignore_tag2 = 1;
9057       else if (unformat (input, "cos1"))
9058         cos1 = 1;
9059       else if (unformat (input, "cos2"))
9060         cos2 = 1;
9061       else if (unformat (input, "dot1q"))
9062         dot1q = 1;
9063       else if (unformat (input, "dot1ad"))
9064         dot1ad = 1;
9065       else
9066         break;
9067     }
9068   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9069        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9070     return 0;
9071
9072   if (tag1 || ignore_tag1 || cos1 || dot1q)
9073     len = 18;
9074   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9075     len = 22;
9076
9077   vec_validate (mask, len - 1);
9078
9079   if (dst)
9080     memset (mask, 0xff, 6);
9081
9082   if (src)
9083     memset (mask + 6, 0xff, 6);
9084
9085   if (tag2 || dot1ad)
9086     {
9087       /* inner vlan tag */
9088       if (tag2)
9089         {
9090           mask[19] = 0xff;
9091           mask[18] = 0x0f;
9092         }
9093       if (cos2)
9094         mask[18] |= 0xe0;
9095       if (proto)
9096         mask[21] = mask[20] = 0xff;
9097       if (tag1)
9098         {
9099           mask[15] = 0xff;
9100           mask[14] = 0x0f;
9101         }
9102       if (cos1)
9103         mask[14] |= 0xe0;
9104       *maskp = mask;
9105       return 1;
9106     }
9107   if (tag1 | dot1q)
9108     {
9109       if (tag1)
9110         {
9111           mask[15] = 0xff;
9112           mask[14] = 0x0f;
9113         }
9114       if (cos1)
9115         mask[14] |= 0xe0;
9116       if (proto)
9117         mask[16] = mask[17] = 0xff;
9118
9119       *maskp = mask;
9120       return 1;
9121     }
9122   if (cos2)
9123     mask[18] |= 0xe0;
9124   if (cos1)
9125     mask[14] |= 0xe0;
9126   if (proto)
9127     mask[12] = mask[13] = 0xff;
9128
9129   *maskp = mask;
9130   return 1;
9131 }
9132
9133 uword
9134 unformat_classify_mask (unformat_input_t * input, va_list * args)
9135 {
9136   u8 **maskp = va_arg (*args, u8 **);
9137   u32 *skipp = va_arg (*args, u32 *);
9138   u32 *matchp = va_arg (*args, u32 *);
9139   u32 match;
9140   u8 *mask = 0;
9141   u8 *l2 = 0;
9142   u8 *l3 = 0;
9143   u8 *l4 = 0;
9144   int i;
9145
9146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9149         ;
9150       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9151         ;
9152       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9153         ;
9154       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9155         ;
9156       else
9157         break;
9158     }
9159
9160   if (l4 && !l3)
9161     {
9162       vec_free (mask);
9163       vec_free (l2);
9164       vec_free (l4);
9165       return 0;
9166     }
9167
9168   if (mask || l2 || l3 || l4)
9169     {
9170       if (l2 || l3 || l4)
9171         {
9172           /* "With a free Ethernet header in every package" */
9173           if (l2 == 0)
9174             vec_validate (l2, 13);
9175           mask = l2;
9176           if (vec_len (l3))
9177             {
9178               vec_append (mask, l3);
9179               vec_free (l3);
9180             }
9181           if (vec_len (l4))
9182             {
9183               vec_append (mask, l4);
9184               vec_free (l4);
9185             }
9186         }
9187
9188       /* Scan forward looking for the first significant mask octet */
9189       for (i = 0; i < vec_len (mask); i++)
9190         if (mask[i])
9191           break;
9192
9193       /* compute (skip, match) params */
9194       *skipp = i / sizeof (u32x4);
9195       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9196
9197       /* Pad mask to an even multiple of the vector size */
9198       while (vec_len (mask) % sizeof (u32x4))
9199         vec_add1 (mask, 0);
9200
9201       match = vec_len (mask) / sizeof (u32x4);
9202
9203       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9204         {
9205           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9206           if (*tmp || *(tmp + 1))
9207             break;
9208           match--;
9209         }
9210       if (match == 0)
9211         clib_warning ("BUG: match 0");
9212
9213       _vec_len (mask) = match * sizeof (u32x4);
9214
9215       *matchp = match;
9216       *maskp = mask;
9217
9218       return 1;
9219     }
9220
9221   return 0;
9222 }
9223 #endif /* VPP_API_TEST_BUILTIN */
9224
9225 #define foreach_l2_next                         \
9226 _(drop, DROP)                                   \
9227 _(ethernet, ETHERNET_INPUT)                     \
9228 _(ip4, IP4_INPUT)                               \
9229 _(ip6, IP6_INPUT)
9230
9231 uword
9232 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9233 {
9234   u32 *miss_next_indexp = va_arg (*args, u32 *);
9235   u32 next_index = 0;
9236   u32 tmp;
9237
9238 #define _(n,N) \
9239   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9240   foreach_l2_next;
9241 #undef _
9242
9243   if (unformat (input, "%d", &tmp))
9244     {
9245       next_index = tmp;
9246       goto out;
9247     }
9248
9249   return 0;
9250
9251 out:
9252   *miss_next_indexp = next_index;
9253   return 1;
9254 }
9255
9256 #define foreach_ip_next                         \
9257 _(drop, DROP)                                   \
9258 _(local, LOCAL)                                 \
9259 _(rewrite, REWRITE)
9260
9261 uword
9262 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9263 {
9264   u32 *miss_next_indexp = va_arg (*args, u32 *);
9265   u32 next_index = 0;
9266   u32 tmp;
9267
9268 #define _(n,N) \
9269   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9270   foreach_ip_next;
9271 #undef _
9272
9273   if (unformat (input, "%d", &tmp))
9274     {
9275       next_index = tmp;
9276       goto out;
9277     }
9278
9279   return 0;
9280
9281 out:
9282   *miss_next_indexp = next_index;
9283   return 1;
9284 }
9285
9286 #define foreach_acl_next                        \
9287 _(deny, DENY)
9288
9289 uword
9290 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9291 {
9292   u32 *miss_next_indexp = va_arg (*args, u32 *);
9293   u32 next_index = 0;
9294   u32 tmp;
9295
9296 #define _(n,N) \
9297   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9298   foreach_acl_next;
9299 #undef _
9300
9301   if (unformat (input, "permit"))
9302     {
9303       next_index = ~0;
9304       goto out;
9305     }
9306   else if (unformat (input, "%d", &tmp))
9307     {
9308       next_index = tmp;
9309       goto out;
9310     }
9311
9312   return 0;
9313
9314 out:
9315   *miss_next_indexp = next_index;
9316   return 1;
9317 }
9318
9319 uword
9320 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9321 {
9322   u32 *r = va_arg (*args, u32 *);
9323
9324   if (unformat (input, "conform-color"))
9325     *r = POLICE_CONFORM;
9326   else if (unformat (input, "exceed-color"))
9327     *r = POLICE_EXCEED;
9328   else
9329     return 0;
9330
9331   return 1;
9332 }
9333
9334 static int
9335 api_classify_add_del_table (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_classify_add_del_table_t *mp;
9339
9340   u32 nbuckets = 2;
9341   u32 skip = ~0;
9342   u32 match = ~0;
9343   int is_add = 1;
9344   int del_chain = 0;
9345   u32 table_index = ~0;
9346   u32 next_table_index = ~0;
9347   u32 miss_next_index = ~0;
9348   u32 memory_size = 32 << 20;
9349   u8 *mask = 0;
9350   u32 current_data_flag = 0;
9351   int current_data_offset = 0;
9352   int ret;
9353
9354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9355     {
9356       if (unformat (i, "del"))
9357         is_add = 0;
9358       else if (unformat (i, "del-chain"))
9359         {
9360           is_add = 0;
9361           del_chain = 1;
9362         }
9363       else if (unformat (i, "buckets %d", &nbuckets))
9364         ;
9365       else if (unformat (i, "memory_size %d", &memory_size))
9366         ;
9367       else if (unformat (i, "skip %d", &skip))
9368         ;
9369       else if (unformat (i, "match %d", &match))
9370         ;
9371       else if (unformat (i, "table %d", &table_index))
9372         ;
9373       else if (unformat (i, "mask %U", unformat_classify_mask,
9374                          &mask, &skip, &match))
9375         ;
9376       else if (unformat (i, "next-table %d", &next_table_index))
9377         ;
9378       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9379                          &miss_next_index))
9380         ;
9381       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9382                          &miss_next_index))
9383         ;
9384       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9385                          &miss_next_index))
9386         ;
9387       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9388         ;
9389       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9390         ;
9391       else
9392         break;
9393     }
9394
9395   if (is_add && mask == 0)
9396     {
9397       errmsg ("Mask required");
9398       return -99;
9399     }
9400
9401   if (is_add && skip == ~0)
9402     {
9403       errmsg ("skip count required");
9404       return -99;
9405     }
9406
9407   if (is_add && match == ~0)
9408     {
9409       errmsg ("match count required");
9410       return -99;
9411     }
9412
9413   if (!is_add && table_index == ~0)
9414     {
9415       errmsg ("table index required for delete");
9416       return -99;
9417     }
9418
9419   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9420
9421   mp->is_add = is_add;
9422   mp->del_chain = del_chain;
9423   mp->table_index = ntohl (table_index);
9424   mp->nbuckets = ntohl (nbuckets);
9425   mp->memory_size = ntohl (memory_size);
9426   mp->skip_n_vectors = ntohl (skip);
9427   mp->match_n_vectors = ntohl (match);
9428   mp->next_table_index = ntohl (next_table_index);
9429   mp->miss_next_index = ntohl (miss_next_index);
9430   mp->current_data_flag = ntohl (current_data_flag);
9431   mp->current_data_offset = ntohl (current_data_offset);
9432   clib_memcpy (mp->mask, mask, vec_len (mask));
9433
9434   vec_free (mask);
9435
9436   S (mp);
9437   W (ret);
9438   return ret;
9439 }
9440
9441 #if VPP_API_TEST_BUILTIN == 0
9442 uword
9443 unformat_l4_match (unformat_input_t * input, va_list * args)
9444 {
9445   u8 **matchp = va_arg (*args, u8 **);
9446
9447   u8 *proto_header = 0;
9448   int src_port = 0;
9449   int dst_port = 0;
9450
9451   tcpudp_header_t h;
9452
9453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (unformat (input, "src_port %d", &src_port))
9456         ;
9457       else if (unformat (input, "dst_port %d", &dst_port))
9458         ;
9459       else
9460         return 0;
9461     }
9462
9463   h.src_port = clib_host_to_net_u16 (src_port);
9464   h.dst_port = clib_host_to_net_u16 (dst_port);
9465   vec_validate (proto_header, sizeof (h) - 1);
9466   memcpy (proto_header, &h, sizeof (h));
9467
9468   *matchp = proto_header;
9469
9470   return 1;
9471 }
9472
9473 uword
9474 unformat_ip4_match (unformat_input_t * input, va_list * args)
9475 {
9476   u8 **matchp = va_arg (*args, u8 **);
9477   u8 *match = 0;
9478   ip4_header_t *ip;
9479   int version = 0;
9480   u32 version_val;
9481   int hdr_length = 0;
9482   u32 hdr_length_val;
9483   int src = 0, dst = 0;
9484   ip4_address_t src_val, dst_val;
9485   int proto = 0;
9486   u32 proto_val;
9487   int tos = 0;
9488   u32 tos_val;
9489   int length = 0;
9490   u32 length_val;
9491   int fragment_id = 0;
9492   u32 fragment_id_val;
9493   int ttl = 0;
9494   int ttl_val;
9495   int checksum = 0;
9496   u32 checksum_val;
9497
9498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9499     {
9500       if (unformat (input, "version %d", &version_val))
9501         version = 1;
9502       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9503         hdr_length = 1;
9504       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9505         src = 1;
9506       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9507         dst = 1;
9508       else if (unformat (input, "proto %d", &proto_val))
9509         proto = 1;
9510       else if (unformat (input, "tos %d", &tos_val))
9511         tos = 1;
9512       else if (unformat (input, "length %d", &length_val))
9513         length = 1;
9514       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9515         fragment_id = 1;
9516       else if (unformat (input, "ttl %d", &ttl_val))
9517         ttl = 1;
9518       else if (unformat (input, "checksum %d", &checksum_val))
9519         checksum = 1;
9520       else
9521         break;
9522     }
9523
9524   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9525       + ttl + checksum == 0)
9526     return 0;
9527
9528   /*
9529    * Aligned because we use the real comparison functions
9530    */
9531   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9532
9533   ip = (ip4_header_t *) match;
9534
9535   /* These are realistically matched in practice */
9536   if (src)
9537     ip->src_address.as_u32 = src_val.as_u32;
9538
9539   if (dst)
9540     ip->dst_address.as_u32 = dst_val.as_u32;
9541
9542   if (proto)
9543     ip->protocol = proto_val;
9544
9545
9546   /* These are not, but they're included for completeness */
9547   if (version)
9548     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9549
9550   if (hdr_length)
9551     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9552
9553   if (tos)
9554     ip->tos = tos_val;
9555
9556   if (length)
9557     ip->length = clib_host_to_net_u16 (length_val);
9558
9559   if (ttl)
9560     ip->ttl = ttl_val;
9561
9562   if (checksum)
9563     ip->checksum = clib_host_to_net_u16 (checksum_val);
9564
9565   *matchp = match;
9566   return 1;
9567 }
9568
9569 uword
9570 unformat_ip6_match (unformat_input_t * input, va_list * args)
9571 {
9572   u8 **matchp = va_arg (*args, u8 **);
9573   u8 *match = 0;
9574   ip6_header_t *ip;
9575   int version = 0;
9576   u32 version_val;
9577   u8 traffic_class = 0;
9578   u32 traffic_class_val = 0;
9579   u8 flow_label = 0;
9580   u8 flow_label_val;
9581   int src = 0, dst = 0;
9582   ip6_address_t src_val, dst_val;
9583   int proto = 0;
9584   u32 proto_val;
9585   int payload_length = 0;
9586   u32 payload_length_val;
9587   int hop_limit = 0;
9588   int hop_limit_val;
9589   u32 ip_version_traffic_class_and_flow_label;
9590
9591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (input, "version %d", &version_val))
9594         version = 1;
9595       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9596         traffic_class = 1;
9597       else if (unformat (input, "flow_label %d", &flow_label_val))
9598         flow_label = 1;
9599       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9600         src = 1;
9601       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9602         dst = 1;
9603       else if (unformat (input, "proto %d", &proto_val))
9604         proto = 1;
9605       else if (unformat (input, "payload_length %d", &payload_length_val))
9606         payload_length = 1;
9607       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9608         hop_limit = 1;
9609       else
9610         break;
9611     }
9612
9613   if (version + traffic_class + flow_label + src + dst + proto +
9614       payload_length + hop_limit == 0)
9615     return 0;
9616
9617   /*
9618    * Aligned because we use the real comparison functions
9619    */
9620   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9621
9622   ip = (ip6_header_t *) match;
9623
9624   if (src)
9625     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9626
9627   if (dst)
9628     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9629
9630   if (proto)
9631     ip->protocol = proto_val;
9632
9633   ip_version_traffic_class_and_flow_label = 0;
9634
9635   if (version)
9636     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9637
9638   if (traffic_class)
9639     ip_version_traffic_class_and_flow_label |=
9640       (traffic_class_val & 0xFF) << 20;
9641
9642   if (flow_label)
9643     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9644
9645   ip->ip_version_traffic_class_and_flow_label =
9646     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9647
9648   if (payload_length)
9649     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9650
9651   if (hop_limit)
9652     ip->hop_limit = hop_limit_val;
9653
9654   *matchp = match;
9655   return 1;
9656 }
9657
9658 uword
9659 unformat_l3_match (unformat_input_t * input, va_list * args)
9660 {
9661   u8 **matchp = va_arg (*args, u8 **);
9662
9663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9664     {
9665       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9666         return 1;
9667       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9668         return 1;
9669       else
9670         break;
9671     }
9672   return 0;
9673 }
9674
9675 uword
9676 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9677 {
9678   u8 *tagp = va_arg (*args, u8 *);
9679   u32 tag;
9680
9681   if (unformat (input, "%d", &tag))
9682     {
9683       tagp[0] = (tag >> 8) & 0x0F;
9684       tagp[1] = tag & 0xFF;
9685       return 1;
9686     }
9687
9688   return 0;
9689 }
9690
9691 uword
9692 unformat_l2_match (unformat_input_t * input, va_list * args)
9693 {
9694   u8 **matchp = va_arg (*args, u8 **);
9695   u8 *match = 0;
9696   u8 src = 0;
9697   u8 src_val[6];
9698   u8 dst = 0;
9699   u8 dst_val[6];
9700   u8 proto = 0;
9701   u16 proto_val;
9702   u8 tag1 = 0;
9703   u8 tag1_val[2];
9704   u8 tag2 = 0;
9705   u8 tag2_val[2];
9706   int len = 14;
9707   u8 ignore_tag1 = 0;
9708   u8 ignore_tag2 = 0;
9709   u8 cos1 = 0;
9710   u8 cos2 = 0;
9711   u32 cos1_val = 0;
9712   u32 cos2_val = 0;
9713
9714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9715     {
9716       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9717         src = 1;
9718       else
9719         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9720         dst = 1;
9721       else if (unformat (input, "proto %U",
9722                          unformat_ethernet_type_host_byte_order, &proto_val))
9723         proto = 1;
9724       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9725         tag1 = 1;
9726       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9727         tag2 = 1;
9728       else if (unformat (input, "ignore-tag1"))
9729         ignore_tag1 = 1;
9730       else if (unformat (input, "ignore-tag2"))
9731         ignore_tag2 = 1;
9732       else if (unformat (input, "cos1 %d", &cos1_val))
9733         cos1 = 1;
9734       else if (unformat (input, "cos2 %d", &cos2_val))
9735         cos2 = 1;
9736       else
9737         break;
9738     }
9739   if ((src + dst + proto + tag1 + tag2 +
9740        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9741     return 0;
9742
9743   if (tag1 || ignore_tag1 || cos1)
9744     len = 18;
9745   if (tag2 || ignore_tag2 || cos2)
9746     len = 22;
9747
9748   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9749
9750   if (dst)
9751     clib_memcpy (match, dst_val, 6);
9752
9753   if (src)
9754     clib_memcpy (match + 6, src_val, 6);
9755
9756   if (tag2)
9757     {
9758       /* inner vlan tag */
9759       match[19] = tag2_val[1];
9760       match[18] = tag2_val[0];
9761       if (cos2)
9762         match[18] |= (cos2_val & 0x7) << 5;
9763       if (proto)
9764         {
9765           match[21] = proto_val & 0xff;
9766           match[20] = proto_val >> 8;
9767         }
9768       if (tag1)
9769         {
9770           match[15] = tag1_val[1];
9771           match[14] = tag1_val[0];
9772         }
9773       if (cos1)
9774         match[14] |= (cos1_val & 0x7) << 5;
9775       *matchp = match;
9776       return 1;
9777     }
9778   if (tag1)
9779     {
9780       match[15] = tag1_val[1];
9781       match[14] = tag1_val[0];
9782       if (proto)
9783         {
9784           match[17] = proto_val & 0xff;
9785           match[16] = proto_val >> 8;
9786         }
9787       if (cos1)
9788         match[14] |= (cos1_val & 0x7) << 5;
9789
9790       *matchp = match;
9791       return 1;
9792     }
9793   if (cos2)
9794     match[18] |= (cos2_val & 0x7) << 5;
9795   if (cos1)
9796     match[14] |= (cos1_val & 0x7) << 5;
9797   if (proto)
9798     {
9799       match[13] = proto_val & 0xff;
9800       match[12] = proto_val >> 8;
9801     }
9802
9803   *matchp = match;
9804   return 1;
9805 }
9806 #endif
9807
9808 uword
9809 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9810 {
9811   u8 **matchp = va_arg (*args, u8 **);
9812   u32 skip_n_vectors = va_arg (*args, u32);
9813   u32 match_n_vectors = va_arg (*args, u32);
9814
9815   u8 *match = 0;
9816   u8 *l2 = 0;
9817   u8 *l3 = 0;
9818   u8 *l4 = 0;
9819
9820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9821     {
9822       if (unformat (input, "hex %U", unformat_hex_string, &match))
9823         ;
9824       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9825         ;
9826       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9827         ;
9828       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9829         ;
9830       else
9831         break;
9832     }
9833
9834   if (l4 && !l3)
9835     {
9836       vec_free (match);
9837       vec_free (l2);
9838       vec_free (l4);
9839       return 0;
9840     }
9841
9842   if (match || l2 || l3 || l4)
9843     {
9844       if (l2 || l3 || l4)
9845         {
9846           /* "Win a free Ethernet header in every packet" */
9847           if (l2 == 0)
9848             vec_validate_aligned (l2, 13, sizeof (u32x4));
9849           match = l2;
9850           if (vec_len (l3))
9851             {
9852               vec_append_aligned (match, l3, sizeof (u32x4));
9853               vec_free (l3);
9854             }
9855           if (vec_len (l4))
9856             {
9857               vec_append_aligned (match, l4, sizeof (u32x4));
9858               vec_free (l4);
9859             }
9860         }
9861
9862       /* Make sure the vector is big enough even if key is all 0's */
9863       vec_validate_aligned
9864         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9865          sizeof (u32x4));
9866
9867       /* Set size, include skipped vectors */
9868       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9869
9870       *matchp = match;
9871
9872       return 1;
9873     }
9874
9875   return 0;
9876 }
9877
9878 static int
9879 api_classify_add_del_session (vat_main_t * vam)
9880 {
9881   unformat_input_t *i = vam->input;
9882   vl_api_classify_add_del_session_t *mp;
9883   int is_add = 1;
9884   u32 table_index = ~0;
9885   u32 hit_next_index = ~0;
9886   u32 opaque_index = ~0;
9887   u8 *match = 0;
9888   i32 advance = 0;
9889   u32 skip_n_vectors = 0;
9890   u32 match_n_vectors = 0;
9891   u32 action = 0;
9892   u32 metadata = 0;
9893   int ret;
9894
9895   /*
9896    * Warning: you have to supply skip_n and match_n
9897    * because the API client cant simply look at the classify
9898    * table object.
9899    */
9900
9901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9902     {
9903       if (unformat (i, "del"))
9904         is_add = 0;
9905       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9906                          &hit_next_index))
9907         ;
9908       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9909                          &hit_next_index))
9910         ;
9911       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9912                          &hit_next_index))
9913         ;
9914       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9915         ;
9916       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9917         ;
9918       else if (unformat (i, "opaque-index %d", &opaque_index))
9919         ;
9920       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9921         ;
9922       else if (unformat (i, "match_n %d", &match_n_vectors))
9923         ;
9924       else if (unformat (i, "match %U", api_unformat_classify_match,
9925                          &match, skip_n_vectors, match_n_vectors))
9926         ;
9927       else if (unformat (i, "advance %d", &advance))
9928         ;
9929       else if (unformat (i, "table-index %d", &table_index))
9930         ;
9931       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9932         action = 1;
9933       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9934         action = 2;
9935       else if (unformat (i, "action %d", &action))
9936         ;
9937       else if (unformat (i, "metadata %d", &metadata))
9938         ;
9939       else
9940         break;
9941     }
9942
9943   if (table_index == ~0)
9944     {
9945       errmsg ("Table index required");
9946       return -99;
9947     }
9948
9949   if (is_add && match == 0)
9950     {
9951       errmsg ("Match value required");
9952       return -99;
9953     }
9954
9955   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9956
9957   mp->is_add = is_add;
9958   mp->table_index = ntohl (table_index);
9959   mp->hit_next_index = ntohl (hit_next_index);
9960   mp->opaque_index = ntohl (opaque_index);
9961   mp->advance = ntohl (advance);
9962   mp->action = action;
9963   mp->metadata = ntohl (metadata);
9964   clib_memcpy (mp->match, match, vec_len (match));
9965   vec_free (match);
9966
9967   S (mp);
9968   W (ret);
9969   return ret;
9970 }
9971
9972 static int
9973 api_classify_set_interface_ip_table (vat_main_t * vam)
9974 {
9975   unformat_input_t *i = vam->input;
9976   vl_api_classify_set_interface_ip_table_t *mp;
9977   u32 sw_if_index;
9978   int sw_if_index_set;
9979   u32 table_index = ~0;
9980   u8 is_ipv6 = 0;
9981   int ret;
9982
9983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9984     {
9985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9986         sw_if_index_set = 1;
9987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9988         sw_if_index_set = 1;
9989       else if (unformat (i, "table %d", &table_index))
9990         ;
9991       else
9992         {
9993           clib_warning ("parse error '%U'", format_unformat_error, i);
9994           return -99;
9995         }
9996     }
9997
9998   if (sw_if_index_set == 0)
9999     {
10000       errmsg ("missing interface name or sw_if_index");
10001       return -99;
10002     }
10003
10004
10005   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10006
10007   mp->sw_if_index = ntohl (sw_if_index);
10008   mp->table_index = ntohl (table_index);
10009   mp->is_ipv6 = is_ipv6;
10010
10011   S (mp);
10012   W (ret);
10013   return ret;
10014 }
10015
10016 static int
10017 api_classify_set_interface_l2_tables (vat_main_t * vam)
10018 {
10019   unformat_input_t *i = vam->input;
10020   vl_api_classify_set_interface_l2_tables_t *mp;
10021   u32 sw_if_index;
10022   int sw_if_index_set;
10023   u32 ip4_table_index = ~0;
10024   u32 ip6_table_index = ~0;
10025   u32 other_table_index = ~0;
10026   u32 is_input = 1;
10027   int ret;
10028
10029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10030     {
10031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10032         sw_if_index_set = 1;
10033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10034         sw_if_index_set = 1;
10035       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10036         ;
10037       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10038         ;
10039       else if (unformat (i, "other-table %d", &other_table_index))
10040         ;
10041       else if (unformat (i, "is-input %d", &is_input))
10042         ;
10043       else
10044         {
10045           clib_warning ("parse error '%U'", format_unformat_error, i);
10046           return -99;
10047         }
10048     }
10049
10050   if (sw_if_index_set == 0)
10051     {
10052       errmsg ("missing interface name or sw_if_index");
10053       return -99;
10054     }
10055
10056
10057   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10058
10059   mp->sw_if_index = ntohl (sw_if_index);
10060   mp->ip4_table_index = ntohl (ip4_table_index);
10061   mp->ip6_table_index = ntohl (ip6_table_index);
10062   mp->other_table_index = ntohl (other_table_index);
10063   mp->is_input = (u8) is_input;
10064
10065   S (mp);
10066   W (ret);
10067   return ret;
10068 }
10069
10070 static int
10071 api_set_ipfix_exporter (vat_main_t * vam)
10072 {
10073   unformat_input_t *i = vam->input;
10074   vl_api_set_ipfix_exporter_t *mp;
10075   ip4_address_t collector_address;
10076   u8 collector_address_set = 0;
10077   u32 collector_port = ~0;
10078   ip4_address_t src_address;
10079   u8 src_address_set = 0;
10080   u32 vrf_id = ~0;
10081   u32 path_mtu = ~0;
10082   u32 template_interval = ~0;
10083   u8 udp_checksum = 0;
10084   int ret;
10085
10086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10087     {
10088       if (unformat (i, "collector_address %U", unformat_ip4_address,
10089                     &collector_address))
10090         collector_address_set = 1;
10091       else if (unformat (i, "collector_port %d", &collector_port))
10092         ;
10093       else if (unformat (i, "src_address %U", unformat_ip4_address,
10094                          &src_address))
10095         src_address_set = 1;
10096       else if (unformat (i, "vrf_id %d", &vrf_id))
10097         ;
10098       else if (unformat (i, "path_mtu %d", &path_mtu))
10099         ;
10100       else if (unformat (i, "template_interval %d", &template_interval))
10101         ;
10102       else if (unformat (i, "udp_checksum"))
10103         udp_checksum = 1;
10104       else
10105         break;
10106     }
10107
10108   if (collector_address_set == 0)
10109     {
10110       errmsg ("collector_address required");
10111       return -99;
10112     }
10113
10114   if (src_address_set == 0)
10115     {
10116       errmsg ("src_address required");
10117       return -99;
10118     }
10119
10120   M (SET_IPFIX_EXPORTER, mp);
10121
10122   memcpy (mp->collector_address, collector_address.data,
10123           sizeof (collector_address.data));
10124   mp->collector_port = htons ((u16) collector_port);
10125   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10126   mp->vrf_id = htonl (vrf_id);
10127   mp->path_mtu = htonl (path_mtu);
10128   mp->template_interval = htonl (template_interval);
10129   mp->udp_checksum = udp_checksum;
10130
10131   S (mp);
10132   W (ret);
10133   return ret;
10134 }
10135
10136 static int
10137 api_set_ipfix_classify_stream (vat_main_t * vam)
10138 {
10139   unformat_input_t *i = vam->input;
10140   vl_api_set_ipfix_classify_stream_t *mp;
10141   u32 domain_id = 0;
10142   u32 src_port = UDP_DST_PORT_ipfix;
10143   int ret;
10144
10145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (i, "domain %d", &domain_id))
10148         ;
10149       else if (unformat (i, "src_port %d", &src_port))
10150         ;
10151       else
10152         {
10153           errmsg ("unknown input `%U'", format_unformat_error, i);
10154           return -99;
10155         }
10156     }
10157
10158   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10159
10160   mp->domain_id = htonl (domain_id);
10161   mp->src_port = htons ((u16) src_port);
10162
10163   S (mp);
10164   W (ret);
10165   return ret;
10166 }
10167
10168 static int
10169 api_ipfix_classify_table_add_del (vat_main_t * vam)
10170 {
10171   unformat_input_t *i = vam->input;
10172   vl_api_ipfix_classify_table_add_del_t *mp;
10173   int is_add = -1;
10174   u32 classify_table_index = ~0;
10175   u8 ip_version = 0;
10176   u8 transport_protocol = 255;
10177   int ret;
10178
10179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10180     {
10181       if (unformat (i, "add"))
10182         is_add = 1;
10183       else if (unformat (i, "del"))
10184         is_add = 0;
10185       else if (unformat (i, "table %d", &classify_table_index))
10186         ;
10187       else if (unformat (i, "ip4"))
10188         ip_version = 4;
10189       else if (unformat (i, "ip6"))
10190         ip_version = 6;
10191       else if (unformat (i, "tcp"))
10192         transport_protocol = 6;
10193       else if (unformat (i, "udp"))
10194         transport_protocol = 17;
10195       else
10196         {
10197           errmsg ("unknown input `%U'", format_unformat_error, i);
10198           return -99;
10199         }
10200     }
10201
10202   if (is_add == -1)
10203     {
10204       errmsg ("expecting: add|del");
10205       return -99;
10206     }
10207   if (classify_table_index == ~0)
10208     {
10209       errmsg ("classifier table not specified");
10210       return -99;
10211     }
10212   if (ip_version == 0)
10213     {
10214       errmsg ("IP version not specified");
10215       return -99;
10216     }
10217
10218   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10219
10220   mp->is_add = is_add;
10221   mp->table_id = htonl (classify_table_index);
10222   mp->ip_version = ip_version;
10223   mp->transport_protocol = transport_protocol;
10224
10225   S (mp);
10226   W (ret);
10227   return ret;
10228 }
10229
10230 static int
10231 api_get_node_index (vat_main_t * vam)
10232 {
10233   unformat_input_t *i = vam->input;
10234   vl_api_get_node_index_t *mp;
10235   u8 *name = 0;
10236   int ret;
10237
10238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10239     {
10240       if (unformat (i, "node %s", &name))
10241         ;
10242       else
10243         break;
10244     }
10245   if (name == 0)
10246     {
10247       errmsg ("node name required");
10248       return -99;
10249     }
10250   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10251     {
10252       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10253       return -99;
10254     }
10255
10256   M (GET_NODE_INDEX, mp);
10257   clib_memcpy (mp->node_name, name, vec_len (name));
10258   vec_free (name);
10259
10260   S (mp);
10261   W (ret);
10262   return ret;
10263 }
10264
10265 static int
10266 api_get_next_index (vat_main_t * vam)
10267 {
10268   unformat_input_t *i = vam->input;
10269   vl_api_get_next_index_t *mp;
10270   u8 *node_name = 0, *next_node_name = 0;
10271   int ret;
10272
10273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10274     {
10275       if (unformat (i, "node-name %s", &node_name))
10276         ;
10277       else if (unformat (i, "next-node-name %s", &next_node_name))
10278         break;
10279     }
10280
10281   if (node_name == 0)
10282     {
10283       errmsg ("node name required");
10284       return -99;
10285     }
10286   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10287     {
10288       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10289       return -99;
10290     }
10291
10292   if (next_node_name == 0)
10293     {
10294       errmsg ("next node name required");
10295       return -99;
10296     }
10297   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10298     {
10299       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10300       return -99;
10301     }
10302
10303   M (GET_NEXT_INDEX, mp);
10304   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10305   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10306   vec_free (node_name);
10307   vec_free (next_node_name);
10308
10309   S (mp);
10310   W (ret);
10311   return ret;
10312 }
10313
10314 static int
10315 api_add_node_next (vat_main_t * vam)
10316 {
10317   unformat_input_t *i = vam->input;
10318   vl_api_add_node_next_t *mp;
10319   u8 *name = 0;
10320   u8 *next = 0;
10321   int ret;
10322
10323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (i, "node %s", &name))
10326         ;
10327       else if (unformat (i, "next %s", &next))
10328         ;
10329       else
10330         break;
10331     }
10332   if (name == 0)
10333     {
10334       errmsg ("node name required");
10335       return -99;
10336     }
10337   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10338     {
10339       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10340       return -99;
10341     }
10342   if (next == 0)
10343     {
10344       errmsg ("next node required");
10345       return -99;
10346     }
10347   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10348     {
10349       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10350       return -99;
10351     }
10352
10353   M (ADD_NODE_NEXT, mp);
10354   clib_memcpy (mp->node_name, name, vec_len (name));
10355   clib_memcpy (mp->next_name, next, vec_len (next));
10356   vec_free (name);
10357   vec_free (next);
10358
10359   S (mp);
10360   W (ret);
10361   return ret;
10362 }
10363
10364 static int
10365 api_l2tpv3_create_tunnel (vat_main_t * vam)
10366 {
10367   unformat_input_t *i = vam->input;
10368   ip6_address_t client_address, our_address;
10369   int client_address_set = 0;
10370   int our_address_set = 0;
10371   u32 local_session_id = 0;
10372   u32 remote_session_id = 0;
10373   u64 local_cookie = 0;
10374   u64 remote_cookie = 0;
10375   u8 l2_sublayer_present = 0;
10376   vl_api_l2tpv3_create_tunnel_t *mp;
10377   int ret;
10378
10379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10380     {
10381       if (unformat (i, "client_address %U", unformat_ip6_address,
10382                     &client_address))
10383         client_address_set = 1;
10384       else if (unformat (i, "our_address %U", unformat_ip6_address,
10385                          &our_address))
10386         our_address_set = 1;
10387       else if (unformat (i, "local_session_id %d", &local_session_id))
10388         ;
10389       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10390         ;
10391       else if (unformat (i, "local_cookie %lld", &local_cookie))
10392         ;
10393       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10394         ;
10395       else if (unformat (i, "l2-sublayer-present"))
10396         l2_sublayer_present = 1;
10397       else
10398         break;
10399     }
10400
10401   if (client_address_set == 0)
10402     {
10403       errmsg ("client_address required");
10404       return -99;
10405     }
10406
10407   if (our_address_set == 0)
10408     {
10409       errmsg ("our_address required");
10410       return -99;
10411     }
10412
10413   M (L2TPV3_CREATE_TUNNEL, mp);
10414
10415   clib_memcpy (mp->client_address, client_address.as_u8,
10416                sizeof (mp->client_address));
10417
10418   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10419
10420   mp->local_session_id = ntohl (local_session_id);
10421   mp->remote_session_id = ntohl (remote_session_id);
10422   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10423   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10424   mp->l2_sublayer_present = l2_sublayer_present;
10425   mp->is_ipv6 = 1;
10426
10427   S (mp);
10428   W (ret);
10429   return ret;
10430 }
10431
10432 static int
10433 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10434 {
10435   unformat_input_t *i = vam->input;
10436   u32 sw_if_index;
10437   u8 sw_if_index_set = 0;
10438   u64 new_local_cookie = 0;
10439   u64 new_remote_cookie = 0;
10440   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10441   int ret;
10442
10443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10444     {
10445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10446         sw_if_index_set = 1;
10447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10448         sw_if_index_set = 1;
10449       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10450         ;
10451       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10452         ;
10453       else
10454         break;
10455     }
10456
10457   if (sw_if_index_set == 0)
10458     {
10459       errmsg ("missing interface name or sw_if_index");
10460       return -99;
10461     }
10462
10463   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10464
10465   mp->sw_if_index = ntohl (sw_if_index);
10466   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10467   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10468
10469   S (mp);
10470   W (ret);
10471   return ret;
10472 }
10473
10474 static int
10475 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10476 {
10477   unformat_input_t *i = vam->input;
10478   vl_api_l2tpv3_interface_enable_disable_t *mp;
10479   u32 sw_if_index;
10480   u8 sw_if_index_set = 0;
10481   u8 enable_disable = 1;
10482   int ret;
10483
10484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10485     {
10486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10487         sw_if_index_set = 1;
10488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10489         sw_if_index_set = 1;
10490       else if (unformat (i, "enable"))
10491         enable_disable = 1;
10492       else if (unformat (i, "disable"))
10493         enable_disable = 0;
10494       else
10495         break;
10496     }
10497
10498   if (sw_if_index_set == 0)
10499     {
10500       errmsg ("missing interface name or sw_if_index");
10501       return -99;
10502     }
10503
10504   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10505
10506   mp->sw_if_index = ntohl (sw_if_index);
10507   mp->enable_disable = enable_disable;
10508
10509   S (mp);
10510   W (ret);
10511   return ret;
10512 }
10513
10514 static int
10515 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10516 {
10517   unformat_input_t *i = vam->input;
10518   vl_api_l2tpv3_set_lookup_key_t *mp;
10519   u8 key = ~0;
10520   int ret;
10521
10522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10523     {
10524       if (unformat (i, "lookup_v6_src"))
10525         key = L2T_LOOKUP_SRC_ADDRESS;
10526       else if (unformat (i, "lookup_v6_dst"))
10527         key = L2T_LOOKUP_DST_ADDRESS;
10528       else if (unformat (i, "lookup_session_id"))
10529         key = L2T_LOOKUP_SESSION_ID;
10530       else
10531         break;
10532     }
10533
10534   if (key == (u8) ~ 0)
10535     {
10536       errmsg ("l2tp session lookup key unset");
10537       return -99;
10538     }
10539
10540   M (L2TPV3_SET_LOOKUP_KEY, mp);
10541
10542   mp->key = key;
10543
10544   S (mp);
10545   W (ret);
10546   return ret;
10547 }
10548
10549 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10550   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10551 {
10552   vat_main_t *vam = &vat_main;
10553
10554   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10555          format_ip6_address, mp->our_address,
10556          format_ip6_address, mp->client_address,
10557          clib_net_to_host_u32 (mp->sw_if_index));
10558
10559   print (vam->ofp,
10560          "   local cookies %016llx %016llx remote cookie %016llx",
10561          clib_net_to_host_u64 (mp->local_cookie[0]),
10562          clib_net_to_host_u64 (mp->local_cookie[1]),
10563          clib_net_to_host_u64 (mp->remote_cookie));
10564
10565   print (vam->ofp, "   local session-id %d remote session-id %d",
10566          clib_net_to_host_u32 (mp->local_session_id),
10567          clib_net_to_host_u32 (mp->remote_session_id));
10568
10569   print (vam->ofp, "   l2 specific sublayer %s\n",
10570          mp->l2_sublayer_present ? "preset" : "absent");
10571
10572 }
10573
10574 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10575   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10576 {
10577   vat_main_t *vam = &vat_main;
10578   vat_json_node_t *node = NULL;
10579   struct in6_addr addr;
10580
10581   if (VAT_JSON_ARRAY != vam->json_tree.type)
10582     {
10583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10584       vat_json_init_array (&vam->json_tree);
10585     }
10586   node = vat_json_array_add (&vam->json_tree);
10587
10588   vat_json_init_object (node);
10589
10590   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10591   vat_json_object_add_ip6 (node, "our_address", addr);
10592   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10593   vat_json_object_add_ip6 (node, "client_address", addr);
10594
10595   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10596   vat_json_init_array (lc);
10597   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10598   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10599   vat_json_object_add_uint (node, "remote_cookie",
10600                             clib_net_to_host_u64 (mp->remote_cookie));
10601
10602   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10603   vat_json_object_add_uint (node, "local_session_id",
10604                             clib_net_to_host_u32 (mp->local_session_id));
10605   vat_json_object_add_uint (node, "remote_session_id",
10606                             clib_net_to_host_u32 (mp->remote_session_id));
10607   vat_json_object_add_string_copy (node, "l2_sublayer",
10608                                    mp->l2_sublayer_present ? (u8 *) "present"
10609                                    : (u8 *) "absent");
10610 }
10611
10612 static int
10613 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10614 {
10615   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10616   vl_api_control_ping_t *mp_ping;
10617   int ret;
10618
10619   /* Get list of l2tpv3-tunnel interfaces */
10620   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10621   S (mp);
10622
10623   /* Use a control ping for synchronization */
10624   M (CONTROL_PING, mp_ping);
10625   S (mp_ping);
10626
10627   W (ret);
10628   return ret;
10629 }
10630
10631
10632 static void vl_api_sw_interface_tap_details_t_handler
10633   (vl_api_sw_interface_tap_details_t * mp)
10634 {
10635   vat_main_t *vam = &vat_main;
10636
10637   print (vam->ofp, "%-16s %d",
10638          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10639 }
10640
10641 static void vl_api_sw_interface_tap_details_t_handler_json
10642   (vl_api_sw_interface_tap_details_t * mp)
10643 {
10644   vat_main_t *vam = &vat_main;
10645   vat_json_node_t *node = NULL;
10646
10647   if (VAT_JSON_ARRAY != vam->json_tree.type)
10648     {
10649       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10650       vat_json_init_array (&vam->json_tree);
10651     }
10652   node = vat_json_array_add (&vam->json_tree);
10653
10654   vat_json_init_object (node);
10655   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10656   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10657 }
10658
10659 static int
10660 api_sw_interface_tap_dump (vat_main_t * vam)
10661 {
10662   vl_api_sw_interface_tap_dump_t *mp;
10663   vl_api_control_ping_t *mp_ping;
10664   int ret;
10665
10666   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10667   /* Get list of tap interfaces */
10668   M (SW_INTERFACE_TAP_DUMP, mp);
10669   S (mp);
10670
10671   /* Use a control ping for synchronization */
10672   M (CONTROL_PING, mp_ping);
10673   S (mp_ping);
10674
10675   W (ret);
10676   return ret;
10677 }
10678
10679 static uword unformat_vxlan_decap_next
10680   (unformat_input_t * input, va_list * args)
10681 {
10682   u32 *result = va_arg (*args, u32 *);
10683   u32 tmp;
10684
10685   if (unformat (input, "l2"))
10686     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10687   else if (unformat (input, "%d", &tmp))
10688     *result = tmp;
10689   else
10690     return 0;
10691   return 1;
10692 }
10693
10694 static int
10695 api_vxlan_add_del_tunnel (vat_main_t * vam)
10696 {
10697   unformat_input_t *line_input = vam->input;
10698   vl_api_vxlan_add_del_tunnel_t *mp;
10699   ip46_address_t src, dst;
10700   u8 is_add = 1;
10701   u8 ipv4_set = 0, ipv6_set = 0;
10702   u8 src_set = 0;
10703   u8 dst_set = 0;
10704   u8 grp_set = 0;
10705   u32 mcast_sw_if_index = ~0;
10706   u32 encap_vrf_id = 0;
10707   u32 decap_next_index = ~0;
10708   u32 vni = 0;
10709   int ret;
10710
10711   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10712   memset (&src, 0, sizeof src);
10713   memset (&dst, 0, sizeof dst);
10714
10715   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10716     {
10717       if (unformat (line_input, "del"))
10718         is_add = 0;
10719       else
10720         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10721         {
10722           ipv4_set = 1;
10723           src_set = 1;
10724         }
10725       else
10726         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10727         {
10728           ipv4_set = 1;
10729           dst_set = 1;
10730         }
10731       else
10732         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10733         {
10734           ipv6_set = 1;
10735           src_set = 1;
10736         }
10737       else
10738         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10739         {
10740           ipv6_set = 1;
10741           dst_set = 1;
10742         }
10743       else if (unformat (line_input, "group %U %U",
10744                          unformat_ip4_address, &dst.ip4,
10745                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10746         {
10747           grp_set = dst_set = 1;
10748           ipv4_set = 1;
10749         }
10750       else if (unformat (line_input, "group %U",
10751                          unformat_ip4_address, &dst.ip4))
10752         {
10753           grp_set = dst_set = 1;
10754           ipv4_set = 1;
10755         }
10756       else if (unformat (line_input, "group %U %U",
10757                          unformat_ip6_address, &dst.ip6,
10758                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10759         {
10760           grp_set = dst_set = 1;
10761           ipv6_set = 1;
10762         }
10763       else if (unformat (line_input, "group %U",
10764                          unformat_ip6_address, &dst.ip6))
10765         {
10766           grp_set = dst_set = 1;
10767           ipv6_set = 1;
10768         }
10769       else
10770         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10771         ;
10772       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10773         ;
10774       else if (unformat (line_input, "decap-next %U",
10775                          unformat_vxlan_decap_next, &decap_next_index))
10776         ;
10777       else if (unformat (line_input, "vni %d", &vni))
10778         ;
10779       else
10780         {
10781           errmsg ("parse error '%U'", format_unformat_error, line_input);
10782           return -99;
10783         }
10784     }
10785
10786   if (src_set == 0)
10787     {
10788       errmsg ("tunnel src address not specified");
10789       return -99;
10790     }
10791   if (dst_set == 0)
10792     {
10793       errmsg ("tunnel dst address not specified");
10794       return -99;
10795     }
10796
10797   if (grp_set && !ip46_address_is_multicast (&dst))
10798     {
10799       errmsg ("tunnel group address not multicast");
10800       return -99;
10801     }
10802   if (grp_set && mcast_sw_if_index == ~0)
10803     {
10804       errmsg ("tunnel nonexistent multicast device");
10805       return -99;
10806     }
10807   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10808     {
10809       errmsg ("tunnel dst address must be unicast");
10810       return -99;
10811     }
10812
10813
10814   if (ipv4_set && ipv6_set)
10815     {
10816       errmsg ("both IPv4 and IPv6 addresses specified");
10817       return -99;
10818     }
10819
10820   if ((vni == 0) || (vni >> 24))
10821     {
10822       errmsg ("vni not specified or out of range");
10823       return -99;
10824     }
10825
10826   M (VXLAN_ADD_DEL_TUNNEL, mp);
10827
10828   if (ipv6_set)
10829     {
10830       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10831       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10832     }
10833   else
10834     {
10835       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10836       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10837     }
10838   mp->encap_vrf_id = ntohl (encap_vrf_id);
10839   mp->decap_next_index = ntohl (decap_next_index);
10840   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10841   mp->vni = ntohl (vni);
10842   mp->is_add = is_add;
10843   mp->is_ipv6 = ipv6_set;
10844
10845   S (mp);
10846   W (ret);
10847   return ret;
10848 }
10849
10850 static void vl_api_vxlan_tunnel_details_t_handler
10851   (vl_api_vxlan_tunnel_details_t * mp)
10852 {
10853   vat_main_t *vam = &vat_main;
10854   ip46_address_t src, dst;
10855
10856   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10857   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10858
10859   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10860          ntohl (mp->sw_if_index),
10861          format_ip46_address, &src, IP46_TYPE_ANY,
10862          format_ip46_address, &dst, IP46_TYPE_ANY,
10863          ntohl (mp->encap_vrf_id),
10864          ntohl (mp->decap_next_index), ntohl (mp->vni),
10865          ntohl (mp->mcast_sw_if_index));
10866 }
10867
10868 static void vl_api_vxlan_tunnel_details_t_handler_json
10869   (vl_api_vxlan_tunnel_details_t * mp)
10870 {
10871   vat_main_t *vam = &vat_main;
10872   vat_json_node_t *node = NULL;
10873
10874   if (VAT_JSON_ARRAY != vam->json_tree.type)
10875     {
10876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10877       vat_json_init_array (&vam->json_tree);
10878     }
10879   node = vat_json_array_add (&vam->json_tree);
10880
10881   vat_json_init_object (node);
10882   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10883   if (mp->is_ipv6)
10884     {
10885       struct in6_addr ip6;
10886
10887       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10888       vat_json_object_add_ip6 (node, "src_address", ip6);
10889       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10890       vat_json_object_add_ip6 (node, "dst_address", ip6);
10891     }
10892   else
10893     {
10894       struct in_addr ip4;
10895
10896       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10897       vat_json_object_add_ip4 (node, "src_address", ip4);
10898       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10899       vat_json_object_add_ip4 (node, "dst_address", ip4);
10900     }
10901   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10902   vat_json_object_add_uint (node, "decap_next_index",
10903                             ntohl (mp->decap_next_index));
10904   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10905   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10906   vat_json_object_add_uint (node, "mcast_sw_if_index",
10907                             ntohl (mp->mcast_sw_if_index));
10908 }
10909
10910 static int
10911 api_vxlan_tunnel_dump (vat_main_t * vam)
10912 {
10913   unformat_input_t *i = vam->input;
10914   vl_api_vxlan_tunnel_dump_t *mp;
10915   vl_api_control_ping_t *mp_ping;
10916   u32 sw_if_index;
10917   u8 sw_if_index_set = 0;
10918   int ret;
10919
10920   /* Parse args required to build the message */
10921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10922     {
10923       if (unformat (i, "sw_if_index %d", &sw_if_index))
10924         sw_if_index_set = 1;
10925       else
10926         break;
10927     }
10928
10929   if (sw_if_index_set == 0)
10930     {
10931       sw_if_index = ~0;
10932     }
10933
10934   if (!vam->json_output)
10935     {
10936       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10937              "sw_if_index", "src_address", "dst_address",
10938              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10939     }
10940
10941   /* Get list of vxlan-tunnel interfaces */
10942   M (VXLAN_TUNNEL_DUMP, mp);
10943
10944   mp->sw_if_index = htonl (sw_if_index);
10945
10946   S (mp);
10947
10948   /* Use a control ping for synchronization */
10949   M (CONTROL_PING, mp_ping);
10950   S (mp_ping);
10951
10952   W (ret);
10953   return ret;
10954 }
10955
10956 static int
10957 api_gre_add_del_tunnel (vat_main_t * vam)
10958 {
10959   unformat_input_t *line_input = vam->input;
10960   vl_api_gre_add_del_tunnel_t *mp;
10961   ip4_address_t src4, dst4;
10962   u8 is_add = 1;
10963   u8 teb = 0;
10964   u8 src_set = 0;
10965   u8 dst_set = 0;
10966   u32 outer_fib_id = 0;
10967   int ret;
10968
10969   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10970     {
10971       if (unformat (line_input, "del"))
10972         is_add = 0;
10973       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10974         src_set = 1;
10975       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10976         dst_set = 1;
10977       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10978         ;
10979       else if (unformat (line_input, "teb"))
10980         teb = 1;
10981       else
10982         {
10983           errmsg ("parse error '%U'", format_unformat_error, line_input);
10984           return -99;
10985         }
10986     }
10987
10988   if (src_set == 0)
10989     {
10990       errmsg ("tunnel src address not specified");
10991       return -99;
10992     }
10993   if (dst_set == 0)
10994     {
10995       errmsg ("tunnel dst address not specified");
10996       return -99;
10997     }
10998
10999
11000   M (GRE_ADD_DEL_TUNNEL, mp);
11001
11002   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
11003   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
11004   mp->outer_fib_id = ntohl (outer_fib_id);
11005   mp->is_add = is_add;
11006   mp->teb = teb;
11007
11008   S (mp);
11009   W (ret);
11010   return ret;
11011 }
11012
11013 static void vl_api_gre_tunnel_details_t_handler
11014   (vl_api_gre_tunnel_details_t * mp)
11015 {
11016   vat_main_t *vam = &vat_main;
11017
11018   print (vam->ofp, "%11d%15U%15U%6d%14d",
11019          ntohl (mp->sw_if_index),
11020          format_ip4_address, &mp->src_address,
11021          format_ip4_address, &mp->dst_address,
11022          mp->teb, ntohl (mp->outer_fib_id));
11023 }
11024
11025 static void vl_api_gre_tunnel_details_t_handler_json
11026   (vl_api_gre_tunnel_details_t * mp)
11027 {
11028   vat_main_t *vam = &vat_main;
11029   vat_json_node_t *node = NULL;
11030   struct in_addr ip4;
11031
11032   if (VAT_JSON_ARRAY != vam->json_tree.type)
11033     {
11034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11035       vat_json_init_array (&vam->json_tree);
11036     }
11037   node = vat_json_array_add (&vam->json_tree);
11038
11039   vat_json_init_object (node);
11040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11041   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11042   vat_json_object_add_ip4 (node, "src_address", ip4);
11043   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11044   vat_json_object_add_ip4 (node, "dst_address", ip4);
11045   vat_json_object_add_uint (node, "teb", mp->teb);
11046   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11047 }
11048
11049 static int
11050 api_gre_tunnel_dump (vat_main_t * vam)
11051 {
11052   unformat_input_t *i = vam->input;
11053   vl_api_gre_tunnel_dump_t *mp;
11054   vl_api_control_ping_t *mp_ping;
11055   u32 sw_if_index;
11056   u8 sw_if_index_set = 0;
11057   int ret;
11058
11059   /* Parse args required to build the message */
11060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11061     {
11062       if (unformat (i, "sw_if_index %d", &sw_if_index))
11063         sw_if_index_set = 1;
11064       else
11065         break;
11066     }
11067
11068   if (sw_if_index_set == 0)
11069     {
11070       sw_if_index = ~0;
11071     }
11072
11073   if (!vam->json_output)
11074     {
11075       print (vam->ofp, "%11s%15s%15s%6s%14s",
11076              "sw_if_index", "src_address", "dst_address", "teb",
11077              "outer_fib_id");
11078     }
11079
11080   /* Get list of gre-tunnel interfaces */
11081   M (GRE_TUNNEL_DUMP, mp);
11082
11083   mp->sw_if_index = htonl (sw_if_index);
11084
11085   S (mp);
11086
11087   /* Use a control ping for synchronization */
11088   M (CONTROL_PING, mp_ping);
11089   S (mp_ping);
11090
11091   W (ret);
11092   return ret;
11093 }
11094
11095 static int
11096 api_l2_fib_clear_table (vat_main_t * vam)
11097 {
11098 //  unformat_input_t * i = vam->input;
11099   vl_api_l2_fib_clear_table_t *mp;
11100   int ret;
11101
11102   M (L2_FIB_CLEAR_TABLE, mp);
11103
11104   S (mp);
11105   W (ret);
11106   return ret;
11107 }
11108
11109 static int
11110 api_l2_interface_efp_filter (vat_main_t * vam)
11111 {
11112   unformat_input_t *i = vam->input;
11113   vl_api_l2_interface_efp_filter_t *mp;
11114   u32 sw_if_index;
11115   u8 enable = 1;
11116   u8 sw_if_index_set = 0;
11117   int ret;
11118
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11122         sw_if_index_set = 1;
11123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "enable"))
11126         enable = 1;
11127       else if (unformat (i, "disable"))
11128         enable = 0;
11129       else
11130         {
11131           clib_warning ("parse error '%U'", format_unformat_error, i);
11132           return -99;
11133         }
11134     }
11135
11136   if (sw_if_index_set == 0)
11137     {
11138       errmsg ("missing sw_if_index");
11139       return -99;
11140     }
11141
11142   M (L2_INTERFACE_EFP_FILTER, mp);
11143
11144   mp->sw_if_index = ntohl (sw_if_index);
11145   mp->enable_disable = enable;
11146
11147   S (mp);
11148   W (ret);
11149   return ret;
11150 }
11151
11152 #define foreach_vtr_op                          \
11153 _("disable",  L2_VTR_DISABLED)                  \
11154 _("push-1",  L2_VTR_PUSH_1)                     \
11155 _("push-2",  L2_VTR_PUSH_2)                     \
11156 _("pop-1",  L2_VTR_POP_1)                       \
11157 _("pop-2",  L2_VTR_POP_2)                       \
11158 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11159 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11160 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11161 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11162
11163 static int
11164 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11165 {
11166   unformat_input_t *i = vam->input;
11167   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11168   u32 sw_if_index;
11169   u8 sw_if_index_set = 0;
11170   u8 vtr_op_set = 0;
11171   u32 vtr_op = 0;
11172   u32 push_dot1q = 1;
11173   u32 tag1 = ~0;
11174   u32 tag2 = ~0;
11175   int ret;
11176
11177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11180         sw_if_index_set = 1;
11181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11182         sw_if_index_set = 1;
11183       else if (unformat (i, "vtr_op %d", &vtr_op))
11184         vtr_op_set = 1;
11185 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11186       foreach_vtr_op
11187 #undef _
11188         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11189         ;
11190       else if (unformat (i, "tag1 %d", &tag1))
11191         ;
11192       else if (unformat (i, "tag2 %d", &tag2))
11193         ;
11194       else
11195         {
11196           clib_warning ("parse error '%U'", format_unformat_error, i);
11197           return -99;
11198         }
11199     }
11200
11201   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11202     {
11203       errmsg ("missing vtr operation or sw_if_index");
11204       return -99;
11205     }
11206
11207   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11208   mp->sw_if_index = ntohl (sw_if_index);
11209   mp->vtr_op = ntohl (vtr_op);
11210   mp->push_dot1q = ntohl (push_dot1q);
11211   mp->tag1 = ntohl (tag1);
11212   mp->tag2 = ntohl (tag2);
11213
11214   S (mp);
11215   W (ret);
11216   return ret;
11217 }
11218
11219 static int
11220 api_create_vhost_user_if (vat_main_t * vam)
11221 {
11222   unformat_input_t *i = vam->input;
11223   vl_api_create_vhost_user_if_t *mp;
11224   u8 *file_name;
11225   u8 is_server = 0;
11226   u8 file_name_set = 0;
11227   u32 custom_dev_instance = ~0;
11228   u8 hwaddr[6];
11229   u8 use_custom_mac = 0;
11230   u8 *tag = 0;
11231   int ret;
11232
11233   /* Shut up coverity */
11234   memset (hwaddr, 0, sizeof (hwaddr));
11235
11236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11237     {
11238       if (unformat (i, "socket %s", &file_name))
11239         {
11240           file_name_set = 1;
11241         }
11242       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11243         ;
11244       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11245         use_custom_mac = 1;
11246       else if (unformat (i, "server"))
11247         is_server = 1;
11248       else if (unformat (i, "tag %s", &tag))
11249         ;
11250       else
11251         break;
11252     }
11253
11254   if (file_name_set == 0)
11255     {
11256       errmsg ("missing socket file name");
11257       return -99;
11258     }
11259
11260   if (vec_len (file_name) > 255)
11261     {
11262       errmsg ("socket file name too long");
11263       return -99;
11264     }
11265   vec_add1 (file_name, 0);
11266
11267   M (CREATE_VHOST_USER_IF, mp);
11268
11269   mp->is_server = is_server;
11270   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11271   vec_free (file_name);
11272   if (custom_dev_instance != ~0)
11273     {
11274       mp->renumber = 1;
11275       mp->custom_dev_instance = ntohl (custom_dev_instance);
11276     }
11277   mp->use_custom_mac = use_custom_mac;
11278   clib_memcpy (mp->mac_address, hwaddr, 6);
11279   if (tag)
11280     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11281   vec_free (tag);
11282
11283   S (mp);
11284   W (ret);
11285   return ret;
11286 }
11287
11288 static int
11289 api_modify_vhost_user_if (vat_main_t * vam)
11290 {
11291   unformat_input_t *i = vam->input;
11292   vl_api_modify_vhost_user_if_t *mp;
11293   u8 *file_name;
11294   u8 is_server = 0;
11295   u8 file_name_set = 0;
11296   u32 custom_dev_instance = ~0;
11297   u8 sw_if_index_set = 0;
11298   u32 sw_if_index = (u32) ~ 0;
11299   int ret;
11300
11301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11302     {
11303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11304         sw_if_index_set = 1;
11305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11306         sw_if_index_set = 1;
11307       else if (unformat (i, "socket %s", &file_name))
11308         {
11309           file_name_set = 1;
11310         }
11311       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11312         ;
11313       else if (unformat (i, "server"))
11314         is_server = 1;
11315       else
11316         break;
11317     }
11318
11319   if (sw_if_index_set == 0)
11320     {
11321       errmsg ("missing sw_if_index or interface name");
11322       return -99;
11323     }
11324
11325   if (file_name_set == 0)
11326     {
11327       errmsg ("missing socket file name");
11328       return -99;
11329     }
11330
11331   if (vec_len (file_name) > 255)
11332     {
11333       errmsg ("socket file name too long");
11334       return -99;
11335     }
11336   vec_add1 (file_name, 0);
11337
11338   M (MODIFY_VHOST_USER_IF, mp);
11339
11340   mp->sw_if_index = ntohl (sw_if_index);
11341   mp->is_server = is_server;
11342   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11343   vec_free (file_name);
11344   if (custom_dev_instance != ~0)
11345     {
11346       mp->renumber = 1;
11347       mp->custom_dev_instance = ntohl (custom_dev_instance);
11348     }
11349
11350   S (mp);
11351   W (ret);
11352   return ret;
11353 }
11354
11355 static int
11356 api_delete_vhost_user_if (vat_main_t * vam)
11357 {
11358   unformat_input_t *i = vam->input;
11359   vl_api_delete_vhost_user_if_t *mp;
11360   u32 sw_if_index = ~0;
11361   u8 sw_if_index_set = 0;
11362   int ret;
11363
11364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11365     {
11366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11367         sw_if_index_set = 1;
11368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11369         sw_if_index_set = 1;
11370       else
11371         break;
11372     }
11373
11374   if (sw_if_index_set == 0)
11375     {
11376       errmsg ("missing sw_if_index or interface name");
11377       return -99;
11378     }
11379
11380
11381   M (DELETE_VHOST_USER_IF, mp);
11382
11383   mp->sw_if_index = ntohl (sw_if_index);
11384
11385   S (mp);
11386   W (ret);
11387   return ret;
11388 }
11389
11390 static void vl_api_sw_interface_vhost_user_details_t_handler
11391   (vl_api_sw_interface_vhost_user_details_t * mp)
11392 {
11393   vat_main_t *vam = &vat_main;
11394
11395   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11396          (char *) mp->interface_name,
11397          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11398          clib_net_to_host_u64 (mp->features), mp->is_server,
11399          ntohl (mp->num_regions), (char *) mp->sock_filename);
11400   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11401 }
11402
11403 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11404   (vl_api_sw_interface_vhost_user_details_t * mp)
11405 {
11406   vat_main_t *vam = &vat_main;
11407   vat_json_node_t *node = NULL;
11408
11409   if (VAT_JSON_ARRAY != vam->json_tree.type)
11410     {
11411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11412       vat_json_init_array (&vam->json_tree);
11413     }
11414   node = vat_json_array_add (&vam->json_tree);
11415
11416   vat_json_init_object (node);
11417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11418   vat_json_object_add_string_copy (node, "interface_name",
11419                                    mp->interface_name);
11420   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11421                             ntohl (mp->virtio_net_hdr_sz));
11422   vat_json_object_add_uint (node, "features",
11423                             clib_net_to_host_u64 (mp->features));
11424   vat_json_object_add_uint (node, "is_server", mp->is_server);
11425   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11426   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11427   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11428 }
11429
11430 static int
11431 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11432 {
11433   vl_api_sw_interface_vhost_user_dump_t *mp;
11434   vl_api_control_ping_t *mp_ping;
11435   int ret;
11436   print (vam->ofp,
11437          "Interface name           idx hdr_sz features server regions filename");
11438
11439   /* Get list of vhost-user interfaces */
11440   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11441   S (mp);
11442
11443   /* Use a control ping for synchronization */
11444   M (CONTROL_PING, mp_ping);
11445   S (mp_ping);
11446
11447   W (ret);
11448   return ret;
11449 }
11450
11451 static int
11452 api_show_version (vat_main_t * vam)
11453 {
11454   vl_api_show_version_t *mp;
11455   int ret;
11456
11457   M (SHOW_VERSION, mp);
11458
11459   S (mp);
11460   W (ret);
11461   return ret;
11462 }
11463
11464
11465 static int
11466 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11467 {
11468   unformat_input_t *line_input = vam->input;
11469   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11470   ip4_address_t local4, remote4;
11471   ip6_address_t local6, remote6;
11472   u8 is_add = 1;
11473   u8 ipv4_set = 0, ipv6_set = 0;
11474   u8 local_set = 0;
11475   u8 remote_set = 0;
11476   u32 encap_vrf_id = 0;
11477   u32 decap_vrf_id = 0;
11478   u8 protocol = ~0;
11479   u32 vni;
11480   u8 vni_set = 0;
11481   int ret;
11482
11483   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (line_input, "del"))
11486         is_add = 0;
11487       else if (unformat (line_input, "local %U",
11488                          unformat_ip4_address, &local4))
11489         {
11490           local_set = 1;
11491           ipv4_set = 1;
11492         }
11493       else if (unformat (line_input, "remote %U",
11494                          unformat_ip4_address, &remote4))
11495         {
11496           remote_set = 1;
11497           ipv4_set = 1;
11498         }
11499       else if (unformat (line_input, "local %U",
11500                          unformat_ip6_address, &local6))
11501         {
11502           local_set = 1;
11503           ipv6_set = 1;
11504         }
11505       else if (unformat (line_input, "remote %U",
11506                          unformat_ip6_address, &remote6))
11507         {
11508           remote_set = 1;
11509           ipv6_set = 1;
11510         }
11511       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11512         ;
11513       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11514         ;
11515       else if (unformat (line_input, "vni %d", &vni))
11516         vni_set = 1;
11517       else if (unformat (line_input, "next-ip4"))
11518         protocol = 1;
11519       else if (unformat (line_input, "next-ip6"))
11520         protocol = 2;
11521       else if (unformat (line_input, "next-ethernet"))
11522         protocol = 3;
11523       else if (unformat (line_input, "next-nsh"))
11524         protocol = 4;
11525       else
11526         {
11527           errmsg ("parse error '%U'", format_unformat_error, line_input);
11528           return -99;
11529         }
11530     }
11531
11532   if (local_set == 0)
11533     {
11534       errmsg ("tunnel local address not specified");
11535       return -99;
11536     }
11537   if (remote_set == 0)
11538     {
11539       errmsg ("tunnel remote address not specified");
11540       return -99;
11541     }
11542   if (ipv4_set && ipv6_set)
11543     {
11544       errmsg ("both IPv4 and IPv6 addresses specified");
11545       return -99;
11546     }
11547
11548   if (vni_set == 0)
11549     {
11550       errmsg ("vni not specified");
11551       return -99;
11552     }
11553
11554   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11555
11556
11557   if (ipv6_set)
11558     {
11559       clib_memcpy (&mp->local, &local6, sizeof (local6));
11560       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11561     }
11562   else
11563     {
11564       clib_memcpy (&mp->local, &local4, sizeof (local4));
11565       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11566     }
11567
11568   mp->encap_vrf_id = ntohl (encap_vrf_id);
11569   mp->decap_vrf_id = ntohl (decap_vrf_id);
11570   mp->protocol = protocol;
11571   mp->vni = ntohl (vni);
11572   mp->is_add = is_add;
11573   mp->is_ipv6 = ipv6_set;
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11581   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11582 {
11583   vat_main_t *vam = &vat_main;
11584
11585   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11586          ntohl (mp->sw_if_index),
11587          format_ip46_address, &(mp->local[0]),
11588          format_ip46_address, &(mp->remote[0]),
11589          ntohl (mp->vni),
11590          ntohl (mp->protocol),
11591          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11592 }
11593
11594 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11595   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11596 {
11597   vat_main_t *vam = &vat_main;
11598   vat_json_node_t *node = NULL;
11599   struct in_addr ip4;
11600   struct in6_addr ip6;
11601
11602   if (VAT_JSON_ARRAY != vam->json_tree.type)
11603     {
11604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11605       vat_json_init_array (&vam->json_tree);
11606     }
11607   node = vat_json_array_add (&vam->json_tree);
11608
11609   vat_json_init_object (node);
11610   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11611   if (mp->is_ipv6)
11612     {
11613       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11614       vat_json_object_add_ip6 (node, "local", ip6);
11615       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11616       vat_json_object_add_ip6 (node, "remote", ip6);
11617     }
11618   else
11619     {
11620       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11621       vat_json_object_add_ip4 (node, "local", ip4);
11622       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11623       vat_json_object_add_ip4 (node, "remote", ip4);
11624     }
11625   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11626   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11627   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11628   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11629   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11630 }
11631
11632 static int
11633 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11634 {
11635   unformat_input_t *i = vam->input;
11636   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11637   vl_api_control_ping_t *mp_ping;
11638   u32 sw_if_index;
11639   u8 sw_if_index_set = 0;
11640   int ret;
11641
11642   /* Parse args required to build the message */
11643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11644     {
11645       if (unformat (i, "sw_if_index %d", &sw_if_index))
11646         sw_if_index_set = 1;
11647       else
11648         break;
11649     }
11650
11651   if (sw_if_index_set == 0)
11652     {
11653       sw_if_index = ~0;
11654     }
11655
11656   if (!vam->json_output)
11657     {
11658       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11659              "sw_if_index", "local", "remote", "vni",
11660              "protocol", "encap_vrf_id", "decap_vrf_id");
11661     }
11662
11663   /* Get list of vxlan-tunnel interfaces */
11664   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11665
11666   mp->sw_if_index = htonl (sw_if_index);
11667
11668   S (mp);
11669
11670   /* Use a control ping for synchronization */
11671   M (CONTROL_PING, mp_ping);
11672   S (mp_ping);
11673
11674   W (ret);
11675   return ret;
11676 }
11677
11678 u8 *
11679 format_l2_fib_mac_address (u8 * s, va_list * args)
11680 {
11681   u8 *a = va_arg (*args, u8 *);
11682
11683   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11684                  a[2], a[3], a[4], a[5], a[6], a[7]);
11685 }
11686
11687 static void vl_api_l2_fib_table_entry_t_handler
11688   (vl_api_l2_fib_table_entry_t * mp)
11689 {
11690   vat_main_t *vam = &vat_main;
11691
11692   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11693          "       %d       %d     %d",
11694          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11695          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11696          mp->bvi_mac);
11697 }
11698
11699 static void vl_api_l2_fib_table_entry_t_handler_json
11700   (vl_api_l2_fib_table_entry_t * mp)
11701 {
11702   vat_main_t *vam = &vat_main;
11703   vat_json_node_t *node = NULL;
11704
11705   if (VAT_JSON_ARRAY != vam->json_tree.type)
11706     {
11707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11708       vat_json_init_array (&vam->json_tree);
11709     }
11710   node = vat_json_array_add (&vam->json_tree);
11711
11712   vat_json_init_object (node);
11713   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11714   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11715   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11716   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11717   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11718   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11719 }
11720
11721 static int
11722 api_l2_fib_table_dump (vat_main_t * vam)
11723 {
11724   unformat_input_t *i = vam->input;
11725   vl_api_l2_fib_table_dump_t *mp;
11726   vl_api_control_ping_t *mp_ping;
11727   u32 bd_id;
11728   u8 bd_id_set = 0;
11729   int ret;
11730
11731   /* Parse args required to build the message */
11732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11733     {
11734       if (unformat (i, "bd_id %d", &bd_id))
11735         bd_id_set = 1;
11736       else
11737         break;
11738     }
11739
11740   if (bd_id_set == 0)
11741     {
11742       errmsg ("missing bridge domain");
11743       return -99;
11744     }
11745
11746   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11747
11748   /* Get list of l2 fib entries */
11749   M (L2_FIB_TABLE_DUMP, mp);
11750
11751   mp->bd_id = ntohl (bd_id);
11752   S (mp);
11753
11754   /* Use a control ping for synchronization */
11755   M (CONTROL_PING, mp_ping);
11756   S (mp_ping);
11757
11758   W (ret);
11759   return ret;
11760 }
11761
11762
11763 static int
11764 api_interface_name_renumber (vat_main_t * vam)
11765 {
11766   unformat_input_t *line_input = vam->input;
11767   vl_api_interface_name_renumber_t *mp;
11768   u32 sw_if_index = ~0;
11769   u32 new_show_dev_instance = ~0;
11770   int ret;
11771
11772   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11773     {
11774       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11775                     &sw_if_index))
11776         ;
11777       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11778         ;
11779       else if (unformat (line_input, "new_show_dev_instance %d",
11780                          &new_show_dev_instance))
11781         ;
11782       else
11783         break;
11784     }
11785
11786   if (sw_if_index == ~0)
11787     {
11788       errmsg ("missing interface name or sw_if_index");
11789       return -99;
11790     }
11791
11792   if (new_show_dev_instance == ~0)
11793     {
11794       errmsg ("missing new_show_dev_instance");
11795       return -99;
11796     }
11797
11798   M (INTERFACE_NAME_RENUMBER, mp);
11799
11800   mp->sw_if_index = ntohl (sw_if_index);
11801   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11802
11803   S (mp);
11804   W (ret);
11805   return ret;
11806 }
11807
11808 static int
11809 api_want_ip4_arp_events (vat_main_t * vam)
11810 {
11811   unformat_input_t *line_input = vam->input;
11812   vl_api_want_ip4_arp_events_t *mp;
11813   ip4_address_t address;
11814   int address_set = 0;
11815   u32 enable_disable = 1;
11816   int ret;
11817
11818   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11819     {
11820       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11821         address_set = 1;
11822       else if (unformat (line_input, "del"))
11823         enable_disable = 0;
11824       else
11825         break;
11826     }
11827
11828   if (address_set == 0)
11829     {
11830       errmsg ("missing addresses");
11831       return -99;
11832     }
11833
11834   M (WANT_IP4_ARP_EVENTS, mp);
11835   mp->enable_disable = enable_disable;
11836   mp->pid = getpid ();
11837   mp->address = address.as_u32;
11838
11839   S (mp);
11840   W (ret);
11841   return ret;
11842 }
11843
11844 static int
11845 api_want_ip6_nd_events (vat_main_t * vam)
11846 {
11847   unformat_input_t *line_input = vam->input;
11848   vl_api_want_ip6_nd_events_t *mp;
11849   ip6_address_t address;
11850   int address_set = 0;
11851   u32 enable_disable = 1;
11852   int ret;
11853
11854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11857         address_set = 1;
11858       else if (unformat (line_input, "del"))
11859         enable_disable = 0;
11860       else
11861         break;
11862     }
11863
11864   if (address_set == 0)
11865     {
11866       errmsg ("missing addresses");
11867       return -99;
11868     }
11869
11870   M (WANT_IP6_ND_EVENTS, mp);
11871   mp->enable_disable = enable_disable;
11872   mp->pid = getpid ();
11873   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11874
11875   S (mp);
11876   W (ret);
11877   return ret;
11878 }
11879
11880 static int
11881 api_input_acl_set_interface (vat_main_t * vam)
11882 {
11883   unformat_input_t *i = vam->input;
11884   vl_api_input_acl_set_interface_t *mp;
11885   u32 sw_if_index;
11886   int sw_if_index_set;
11887   u32 ip4_table_index = ~0;
11888   u32 ip6_table_index = ~0;
11889   u32 l2_table_index = ~0;
11890   u8 is_add = 1;
11891   int ret;
11892
11893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11896         sw_if_index_set = 1;
11897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11898         sw_if_index_set = 1;
11899       else if (unformat (i, "del"))
11900         is_add = 0;
11901       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11902         ;
11903       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11904         ;
11905       else if (unformat (i, "l2-table %d", &l2_table_index))
11906         ;
11907       else
11908         {
11909           clib_warning ("parse error '%U'", format_unformat_error, i);
11910           return -99;
11911         }
11912     }
11913
11914   if (sw_if_index_set == 0)
11915     {
11916       errmsg ("missing interface name or sw_if_index");
11917       return -99;
11918     }
11919
11920   M (INPUT_ACL_SET_INTERFACE, mp);
11921
11922   mp->sw_if_index = ntohl (sw_if_index);
11923   mp->ip4_table_index = ntohl (ip4_table_index);
11924   mp->ip6_table_index = ntohl (ip6_table_index);
11925   mp->l2_table_index = ntohl (l2_table_index);
11926   mp->is_add = is_add;
11927
11928   S (mp);
11929   W (ret);
11930   return ret;
11931 }
11932
11933 static int
11934 api_ip_address_dump (vat_main_t * vam)
11935 {
11936   unformat_input_t *i = vam->input;
11937   vl_api_ip_address_dump_t *mp;
11938   vl_api_control_ping_t *mp_ping;
11939   u32 sw_if_index = ~0;
11940   u8 sw_if_index_set = 0;
11941   u8 ipv4_set = 0;
11942   u8 ipv6_set = 0;
11943   int ret;
11944
11945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11946     {
11947       if (unformat (i, "sw_if_index %d", &sw_if_index))
11948         sw_if_index_set = 1;
11949       else
11950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11951         sw_if_index_set = 1;
11952       else if (unformat (i, "ipv4"))
11953         ipv4_set = 1;
11954       else if (unformat (i, "ipv6"))
11955         ipv6_set = 1;
11956       else
11957         break;
11958     }
11959
11960   if (ipv4_set && ipv6_set)
11961     {
11962       errmsg ("ipv4 and ipv6 flags cannot be both set");
11963       return -99;
11964     }
11965
11966   if ((!ipv4_set) && (!ipv6_set))
11967     {
11968       errmsg ("no ipv4 nor ipv6 flag set");
11969       return -99;
11970     }
11971
11972   if (sw_if_index_set == 0)
11973     {
11974       errmsg ("missing interface name or sw_if_index");
11975       return -99;
11976     }
11977
11978   vam->current_sw_if_index = sw_if_index;
11979   vam->is_ipv6 = ipv6_set;
11980
11981   M (IP_ADDRESS_DUMP, mp);
11982   mp->sw_if_index = ntohl (sw_if_index);
11983   mp->is_ipv6 = ipv6_set;
11984   S (mp);
11985
11986   /* Use a control ping for synchronization */
11987   M (CONTROL_PING, mp_ping);
11988   S (mp_ping);
11989
11990   W (ret);
11991   return ret;
11992 }
11993
11994 static int
11995 api_ip_dump (vat_main_t * vam)
11996 {
11997   vl_api_ip_dump_t *mp;
11998   vl_api_control_ping_t *mp_ping;
11999   unformat_input_t *in = vam->input;
12000   int ipv4_set = 0;
12001   int ipv6_set = 0;
12002   int is_ipv6;
12003   int i;
12004   int ret;
12005
12006   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12007     {
12008       if (unformat (in, "ipv4"))
12009         ipv4_set = 1;
12010       else if (unformat (in, "ipv6"))
12011         ipv6_set = 1;
12012       else
12013         break;
12014     }
12015
12016   if (ipv4_set && ipv6_set)
12017     {
12018       errmsg ("ipv4 and ipv6 flags cannot be both set");
12019       return -99;
12020     }
12021
12022   if ((!ipv4_set) && (!ipv6_set))
12023     {
12024       errmsg ("no ipv4 nor ipv6 flag set");
12025       return -99;
12026     }
12027
12028   is_ipv6 = ipv6_set;
12029   vam->is_ipv6 = is_ipv6;
12030
12031   /* free old data */
12032   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12033     {
12034       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12035     }
12036   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12037
12038   M (IP_DUMP, mp);
12039   mp->is_ipv6 = ipv6_set;
12040   S (mp);
12041
12042   /* Use a control ping for synchronization */
12043   M (CONTROL_PING, mp_ping);
12044   S (mp_ping);
12045
12046   W (ret);
12047   return ret;
12048 }
12049
12050 static int
12051 api_ipsec_spd_add_del (vat_main_t * vam)
12052 {
12053   unformat_input_t *i = vam->input;
12054   vl_api_ipsec_spd_add_del_t *mp;
12055   u32 spd_id = ~0;
12056   u8 is_add = 1;
12057   int ret;
12058
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "spd_id %d", &spd_id))
12062         ;
12063       else if (unformat (i, "del"))
12064         is_add = 0;
12065       else
12066         {
12067           clib_warning ("parse error '%U'", format_unformat_error, i);
12068           return -99;
12069         }
12070     }
12071   if (spd_id == ~0)
12072     {
12073       errmsg ("spd_id must be set");
12074       return -99;
12075     }
12076
12077   M (IPSEC_SPD_ADD_DEL, mp);
12078
12079   mp->spd_id = ntohl (spd_id);
12080   mp->is_add = is_add;
12081
12082   S (mp);
12083   W (ret);
12084   return ret;
12085 }
12086
12087 static int
12088 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12089 {
12090   unformat_input_t *i = vam->input;
12091   vl_api_ipsec_interface_add_del_spd_t *mp;
12092   u32 sw_if_index;
12093   u8 sw_if_index_set = 0;
12094   u32 spd_id = (u32) ~ 0;
12095   u8 is_add = 1;
12096   int ret;
12097
12098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12099     {
12100       if (unformat (i, "del"))
12101         is_add = 0;
12102       else if (unformat (i, "spd_id %d", &spd_id))
12103         ;
12104       else
12105         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12106         sw_if_index_set = 1;
12107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12108         sw_if_index_set = 1;
12109       else
12110         {
12111           clib_warning ("parse error '%U'", format_unformat_error, i);
12112           return -99;
12113         }
12114
12115     }
12116
12117   if (spd_id == (u32) ~ 0)
12118     {
12119       errmsg ("spd_id must be set");
12120       return -99;
12121     }
12122
12123   if (sw_if_index_set == 0)
12124     {
12125       errmsg ("missing interface name or sw_if_index");
12126       return -99;
12127     }
12128
12129   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12130
12131   mp->spd_id = ntohl (spd_id);
12132   mp->sw_if_index = ntohl (sw_if_index);
12133   mp->is_add = is_add;
12134
12135   S (mp);
12136   W (ret);
12137   return ret;
12138 }
12139
12140 static int
12141 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12142 {
12143   unformat_input_t *i = vam->input;
12144   vl_api_ipsec_spd_add_del_entry_t *mp;
12145   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12146   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12147   i32 priority = 0;
12148   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12149   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12150   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12151   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12152   int ret;
12153
12154   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12155   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12156   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12157   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12158   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12159   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12160
12161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12162     {
12163       if (unformat (i, "del"))
12164         is_add = 0;
12165       if (unformat (i, "outbound"))
12166         is_outbound = 1;
12167       if (unformat (i, "inbound"))
12168         is_outbound = 0;
12169       else if (unformat (i, "spd_id %d", &spd_id))
12170         ;
12171       else if (unformat (i, "sa_id %d", &sa_id))
12172         ;
12173       else if (unformat (i, "priority %d", &priority))
12174         ;
12175       else if (unformat (i, "protocol %d", &protocol))
12176         ;
12177       else if (unformat (i, "lport_start %d", &lport_start))
12178         ;
12179       else if (unformat (i, "lport_stop %d", &lport_stop))
12180         ;
12181       else if (unformat (i, "rport_start %d", &rport_start))
12182         ;
12183       else if (unformat (i, "rport_stop %d", &rport_stop))
12184         ;
12185       else
12186         if (unformat
12187             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12188         {
12189           is_ipv6 = 0;
12190           is_ip_any = 0;
12191         }
12192       else
12193         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12194         {
12195           is_ipv6 = 0;
12196           is_ip_any = 0;
12197         }
12198       else
12199         if (unformat
12200             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12201         {
12202           is_ipv6 = 0;
12203           is_ip_any = 0;
12204         }
12205       else
12206         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12207         {
12208           is_ipv6 = 0;
12209           is_ip_any = 0;
12210         }
12211       else
12212         if (unformat
12213             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12214         {
12215           is_ipv6 = 1;
12216           is_ip_any = 0;
12217         }
12218       else
12219         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12220         {
12221           is_ipv6 = 1;
12222           is_ip_any = 0;
12223         }
12224       else
12225         if (unformat
12226             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12227         {
12228           is_ipv6 = 1;
12229           is_ip_any = 0;
12230         }
12231       else
12232         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12233         {
12234           is_ipv6 = 1;
12235           is_ip_any = 0;
12236         }
12237       else
12238         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12239         {
12240           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12241             {
12242               clib_warning ("unsupported action: 'resolve'");
12243               return -99;
12244             }
12245         }
12246       else
12247         {
12248           clib_warning ("parse error '%U'", format_unformat_error, i);
12249           return -99;
12250         }
12251
12252     }
12253
12254   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12255
12256   mp->spd_id = ntohl (spd_id);
12257   mp->priority = ntohl (priority);
12258   mp->is_outbound = is_outbound;
12259
12260   mp->is_ipv6 = is_ipv6;
12261   if (is_ipv6 || is_ip_any)
12262     {
12263       clib_memcpy (mp->remote_address_start, &raddr6_start,
12264                    sizeof (ip6_address_t));
12265       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12266                    sizeof (ip6_address_t));
12267       clib_memcpy (mp->local_address_start, &laddr6_start,
12268                    sizeof (ip6_address_t));
12269       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12270                    sizeof (ip6_address_t));
12271     }
12272   else
12273     {
12274       clib_memcpy (mp->remote_address_start, &raddr4_start,
12275                    sizeof (ip4_address_t));
12276       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12277                    sizeof (ip4_address_t));
12278       clib_memcpy (mp->local_address_start, &laddr4_start,
12279                    sizeof (ip4_address_t));
12280       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12281                    sizeof (ip4_address_t));
12282     }
12283   mp->protocol = (u8) protocol;
12284   mp->local_port_start = ntohs ((u16) lport_start);
12285   mp->local_port_stop = ntohs ((u16) lport_stop);
12286   mp->remote_port_start = ntohs ((u16) rport_start);
12287   mp->remote_port_stop = ntohs ((u16) rport_stop);
12288   mp->policy = (u8) policy;
12289   mp->sa_id = ntohl (sa_id);
12290   mp->is_add = is_add;
12291   mp->is_ip_any = is_ip_any;
12292   S (mp);
12293   W (ret);
12294   return ret;
12295 }
12296
12297 static int
12298 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12299 {
12300   unformat_input_t *i = vam->input;
12301   vl_api_ipsec_sad_add_del_entry_t *mp;
12302   u32 sad_id = 0, spi = 0;
12303   u8 *ck = 0, *ik = 0;
12304   u8 is_add = 1;
12305
12306   u8 protocol = IPSEC_PROTOCOL_AH;
12307   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12308   u32 crypto_alg = 0, integ_alg = 0;
12309   ip4_address_t tun_src4;
12310   ip4_address_t tun_dst4;
12311   ip6_address_t tun_src6;
12312   ip6_address_t tun_dst6;
12313   int ret;
12314
12315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (i, "del"))
12318         is_add = 0;
12319       else if (unformat (i, "sad_id %d", &sad_id))
12320         ;
12321       else if (unformat (i, "spi %d", &spi))
12322         ;
12323       else if (unformat (i, "esp"))
12324         protocol = IPSEC_PROTOCOL_ESP;
12325       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12326         {
12327           is_tunnel = 1;
12328           is_tunnel_ipv6 = 0;
12329         }
12330       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12331         {
12332           is_tunnel = 1;
12333           is_tunnel_ipv6 = 0;
12334         }
12335       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12336         {
12337           is_tunnel = 1;
12338           is_tunnel_ipv6 = 1;
12339         }
12340       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12341         {
12342           is_tunnel = 1;
12343           is_tunnel_ipv6 = 1;
12344         }
12345       else
12346         if (unformat
12347             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12348         {
12349           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12350               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12351             {
12352               clib_warning ("unsupported crypto-alg: '%U'",
12353                             format_ipsec_crypto_alg, crypto_alg);
12354               return -99;
12355             }
12356         }
12357       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12358         ;
12359       else
12360         if (unformat
12361             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12362         {
12363           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12364               integ_alg >= IPSEC_INTEG_N_ALG)
12365             {
12366               clib_warning ("unsupported integ-alg: '%U'",
12367                             format_ipsec_integ_alg, integ_alg);
12368               return -99;
12369             }
12370         }
12371       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12372         ;
12373       else
12374         {
12375           clib_warning ("parse error '%U'", format_unformat_error, i);
12376           return -99;
12377         }
12378
12379     }
12380
12381   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12382
12383   mp->sad_id = ntohl (sad_id);
12384   mp->is_add = is_add;
12385   mp->protocol = protocol;
12386   mp->spi = ntohl (spi);
12387   mp->is_tunnel = is_tunnel;
12388   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12389   mp->crypto_algorithm = crypto_alg;
12390   mp->integrity_algorithm = integ_alg;
12391   mp->crypto_key_length = vec_len (ck);
12392   mp->integrity_key_length = vec_len (ik);
12393
12394   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12395     mp->crypto_key_length = sizeof (mp->crypto_key);
12396
12397   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12398     mp->integrity_key_length = sizeof (mp->integrity_key);
12399
12400   if (ck)
12401     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12402   if (ik)
12403     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12404
12405   if (is_tunnel)
12406     {
12407       if (is_tunnel_ipv6)
12408         {
12409           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12410                        sizeof (ip6_address_t));
12411           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12412                        sizeof (ip6_address_t));
12413         }
12414       else
12415         {
12416           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12417                        sizeof (ip4_address_t));
12418           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12419                        sizeof (ip4_address_t));
12420         }
12421     }
12422
12423   S (mp);
12424   W (ret);
12425   return ret;
12426 }
12427
12428 static int
12429 api_ipsec_sa_set_key (vat_main_t * vam)
12430 {
12431   unformat_input_t *i = vam->input;
12432   vl_api_ipsec_sa_set_key_t *mp;
12433   u32 sa_id;
12434   u8 *ck = 0, *ik = 0;
12435   int ret;
12436
12437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12438     {
12439       if (unformat (i, "sa_id %d", &sa_id))
12440         ;
12441       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12442         ;
12443       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12444         ;
12445       else
12446         {
12447           clib_warning ("parse error '%U'", format_unformat_error, i);
12448           return -99;
12449         }
12450     }
12451
12452   M (IPSEC_SA_SET_KEY, mp);
12453
12454   mp->sa_id = ntohl (sa_id);
12455   mp->crypto_key_length = vec_len (ck);
12456   mp->integrity_key_length = vec_len (ik);
12457
12458   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12459     mp->crypto_key_length = sizeof (mp->crypto_key);
12460
12461   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12462     mp->integrity_key_length = sizeof (mp->integrity_key);
12463
12464   if (ck)
12465     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12466   if (ik)
12467     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12468
12469   S (mp);
12470   W (ret);
12471   return ret;
12472 }
12473
12474 static int
12475 api_ikev2_profile_add_del (vat_main_t * vam)
12476 {
12477   unformat_input_t *i = vam->input;
12478   vl_api_ikev2_profile_add_del_t *mp;
12479   u8 is_add = 1;
12480   u8 *name = 0;
12481   int ret;
12482
12483   const char *valid_chars = "a-zA-Z0-9_";
12484
12485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (i, "del"))
12488         is_add = 0;
12489       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12490         vec_add1 (name, 0);
12491       else
12492         {
12493           errmsg ("parse error '%U'", format_unformat_error, i);
12494           return -99;
12495         }
12496     }
12497
12498   if (!vec_len (name))
12499     {
12500       errmsg ("profile name must be specified");
12501       return -99;
12502     }
12503
12504   if (vec_len (name) > 64)
12505     {
12506       errmsg ("profile name too long");
12507       return -99;
12508     }
12509
12510   M (IKEV2_PROFILE_ADD_DEL, mp);
12511
12512   clib_memcpy (mp->name, name, vec_len (name));
12513   mp->is_add = is_add;
12514   vec_free (name);
12515
12516   S (mp);
12517   W (ret);
12518   return ret;
12519 }
12520
12521 static int
12522 api_ikev2_profile_set_auth (vat_main_t * vam)
12523 {
12524   unformat_input_t *i = vam->input;
12525   vl_api_ikev2_profile_set_auth_t *mp;
12526   u8 *name = 0;
12527   u8 *data = 0;
12528   u32 auth_method = 0;
12529   u8 is_hex = 0;
12530   int ret;
12531
12532   const char *valid_chars = "a-zA-Z0-9_";
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12537         vec_add1 (name, 0);
12538       else if (unformat (i, "auth_method %U",
12539                          unformat_ikev2_auth_method, &auth_method))
12540         ;
12541       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12542         is_hex = 1;
12543       else if (unformat (i, "auth_data %v", &data))
12544         ;
12545       else
12546         {
12547           errmsg ("parse error '%U'", format_unformat_error, i);
12548           return -99;
12549         }
12550     }
12551
12552   if (!vec_len (name))
12553     {
12554       errmsg ("profile name must be specified");
12555       return -99;
12556     }
12557
12558   if (vec_len (name) > 64)
12559     {
12560       errmsg ("profile name too long");
12561       return -99;
12562     }
12563
12564   if (!vec_len (data))
12565     {
12566       errmsg ("auth_data must be specified");
12567       return -99;
12568     }
12569
12570   if (!auth_method)
12571     {
12572       errmsg ("auth_method must be specified");
12573       return -99;
12574     }
12575
12576   M (IKEV2_PROFILE_SET_AUTH, mp);
12577
12578   mp->is_hex = is_hex;
12579   mp->auth_method = (u8) auth_method;
12580   mp->data_len = vec_len (data);
12581   clib_memcpy (mp->name, name, vec_len (name));
12582   clib_memcpy (mp->data, data, vec_len (data));
12583   vec_free (name);
12584   vec_free (data);
12585
12586   S (mp);
12587   W (ret);
12588   return ret;
12589 }
12590
12591 static int
12592 api_ikev2_profile_set_id (vat_main_t * vam)
12593 {
12594   unformat_input_t *i = vam->input;
12595   vl_api_ikev2_profile_set_id_t *mp;
12596   u8 *name = 0;
12597   u8 *data = 0;
12598   u8 is_local = 0;
12599   u32 id_type = 0;
12600   ip4_address_t ip4;
12601   int ret;
12602
12603   const char *valid_chars = "a-zA-Z0-9_";
12604
12605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12606     {
12607       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12608         vec_add1 (name, 0);
12609       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12610         ;
12611       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12612         {
12613           data = vec_new (u8, 4);
12614           clib_memcpy (data, ip4.as_u8, 4);
12615         }
12616       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12617         ;
12618       else if (unformat (i, "id_data %v", &data))
12619         ;
12620       else if (unformat (i, "local"))
12621         is_local = 1;
12622       else if (unformat (i, "remote"))
12623         is_local = 0;
12624       else
12625         {
12626           errmsg ("parse error '%U'", format_unformat_error, i);
12627           return -99;
12628         }
12629     }
12630
12631   if (!vec_len (name))
12632     {
12633       errmsg ("profile name must be specified");
12634       return -99;
12635     }
12636
12637   if (vec_len (name) > 64)
12638     {
12639       errmsg ("profile name too long");
12640       return -99;
12641     }
12642
12643   if (!vec_len (data))
12644     {
12645       errmsg ("id_data must be specified");
12646       return -99;
12647     }
12648
12649   if (!id_type)
12650     {
12651       errmsg ("id_type must be specified");
12652       return -99;
12653     }
12654
12655   M (IKEV2_PROFILE_SET_ID, mp);
12656
12657   mp->is_local = is_local;
12658   mp->id_type = (u8) id_type;
12659   mp->data_len = vec_len (data);
12660   clib_memcpy (mp->name, name, vec_len (name));
12661   clib_memcpy (mp->data, data, vec_len (data));
12662   vec_free (name);
12663   vec_free (data);
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_ikev2_profile_set_ts (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_ikev2_profile_set_ts_t *mp;
12675   u8 *name = 0;
12676   u8 is_local = 0;
12677   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12678   ip4_address_t start_addr, end_addr;
12679
12680   const char *valid_chars = "a-zA-Z0-9_";
12681   int ret;
12682
12683   start_addr.as_u32 = 0;
12684   end_addr.as_u32 = (u32) ~ 0;
12685
12686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12687     {
12688       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12689         vec_add1 (name, 0);
12690       else if (unformat (i, "protocol %d", &proto))
12691         ;
12692       else if (unformat (i, "start_port %d", &start_port))
12693         ;
12694       else if (unformat (i, "end_port %d", &end_port))
12695         ;
12696       else
12697         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12698         ;
12699       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12700         ;
12701       else if (unformat (i, "local"))
12702         is_local = 1;
12703       else if (unformat (i, "remote"))
12704         is_local = 0;
12705       else
12706         {
12707           errmsg ("parse error '%U'", format_unformat_error, i);
12708           return -99;
12709         }
12710     }
12711
12712   if (!vec_len (name))
12713     {
12714       errmsg ("profile name must be specified");
12715       return -99;
12716     }
12717
12718   if (vec_len (name) > 64)
12719     {
12720       errmsg ("profile name too long");
12721       return -99;
12722     }
12723
12724   M (IKEV2_PROFILE_SET_TS, mp);
12725
12726   mp->is_local = is_local;
12727   mp->proto = (u8) proto;
12728   mp->start_port = (u16) start_port;
12729   mp->end_port = (u16) end_port;
12730   mp->start_addr = start_addr.as_u32;
12731   mp->end_addr = end_addr.as_u32;
12732   clib_memcpy (mp->name, name, vec_len (name));
12733   vec_free (name);
12734
12735   S (mp);
12736   W (ret);
12737   return ret;
12738 }
12739
12740 static int
12741 api_ikev2_set_local_key (vat_main_t * vam)
12742 {
12743   unformat_input_t *i = vam->input;
12744   vl_api_ikev2_set_local_key_t *mp;
12745   u8 *file = 0;
12746   int ret;
12747
12748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12749     {
12750       if (unformat (i, "file %v", &file))
12751         vec_add1 (file, 0);
12752       else
12753         {
12754           errmsg ("parse error '%U'", format_unformat_error, i);
12755           return -99;
12756         }
12757     }
12758
12759   if (!vec_len (file))
12760     {
12761       errmsg ("RSA key file must be specified");
12762       return -99;
12763     }
12764
12765   if (vec_len (file) > 256)
12766     {
12767       errmsg ("file name too long");
12768       return -99;
12769     }
12770
12771   M (IKEV2_SET_LOCAL_KEY, mp);
12772
12773   clib_memcpy (mp->key_file, file, vec_len (file));
12774   vec_free (file);
12775
12776   S (mp);
12777   W (ret);
12778   return ret;
12779 }
12780
12781 static int
12782 api_ikev2_set_responder (vat_main_t * vam)
12783 {
12784   unformat_input_t *i = vam->input;
12785   vl_api_ikev2_set_responder_t *mp;
12786   int ret;
12787   u8 *name = 0;
12788   u32 sw_if_index = ~0;
12789   ip4_address_t address;
12790
12791   const char *valid_chars = "a-zA-Z0-9_";
12792
12793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12794     {
12795       if (unformat
12796           (i, "%U interface %d address %U", unformat_token, valid_chars,
12797            &name, &sw_if_index, unformat_ip4_address, &address))
12798         vec_add1 (name, 0);
12799       else
12800         {
12801           errmsg ("parse error '%U'", format_unformat_error, i);
12802           return -99;
12803         }
12804     }
12805
12806   if (!vec_len (name))
12807     {
12808       errmsg ("profile name must be specified");
12809       return -99;
12810     }
12811
12812   if (vec_len (name) > 64)
12813     {
12814       errmsg ("profile name too long");
12815       return -99;
12816     }
12817
12818   M (IKEV2_SET_RESPONDER, mp);
12819
12820   clib_memcpy (mp->name, name, vec_len (name));
12821   vec_free (name);
12822
12823   mp->sw_if_index = sw_if_index;
12824   clib_memcpy (mp->address, &address, sizeof (address));
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 static int
12832 api_ikev2_set_ike_transforms (vat_main_t * vam)
12833 {
12834   unformat_input_t *i = vam->input;
12835   vl_api_ikev2_set_ike_transforms_t *mp;
12836   int ret;
12837   u8 *name = 0;
12838   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12839
12840   const char *valid_chars = "a-zA-Z0-9_";
12841
12842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12843     {
12844       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12845                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12846         vec_add1 (name, 0);
12847       else
12848         {
12849           errmsg ("parse error '%U'", format_unformat_error, i);
12850           return -99;
12851         }
12852     }
12853
12854   if (!vec_len (name))
12855     {
12856       errmsg ("profile name must be specified");
12857       return -99;
12858     }
12859
12860   if (vec_len (name) > 64)
12861     {
12862       errmsg ("profile name too long");
12863       return -99;
12864     }
12865
12866   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12867
12868   clib_memcpy (mp->name, name, vec_len (name));
12869   vec_free (name);
12870   mp->crypto_alg = crypto_alg;
12871   mp->crypto_key_size = crypto_key_size;
12872   mp->integ_alg = integ_alg;
12873   mp->dh_group = dh_group;
12874
12875   S (mp);
12876   W (ret);
12877   return ret;
12878 }
12879
12880
12881 static int
12882 api_ikev2_set_esp_transforms (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_ikev2_set_esp_transforms_t *mp;
12886   int ret;
12887   u8 *name = 0;
12888   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12889
12890   const char *valid_chars = "a-zA-Z0-9_";
12891
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12895                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12896         vec_add1 (name, 0);
12897       else
12898         {
12899           errmsg ("parse error '%U'", format_unformat_error, i);
12900           return -99;
12901         }
12902     }
12903
12904   if (!vec_len (name))
12905     {
12906       errmsg ("profile name must be specified");
12907       return -99;
12908     }
12909
12910   if (vec_len (name) > 64)
12911     {
12912       errmsg ("profile name too long");
12913       return -99;
12914     }
12915
12916   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12917
12918   clib_memcpy (mp->name, name, vec_len (name));
12919   vec_free (name);
12920   mp->crypto_alg = crypto_alg;
12921   mp->crypto_key_size = crypto_key_size;
12922   mp->integ_alg = integ_alg;
12923   mp->dh_group = dh_group;
12924
12925   S (mp);
12926   W (ret);
12927   return ret;
12928 }
12929
12930 static int
12931 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12932 {
12933   unformat_input_t *i = vam->input;
12934   vl_api_ikev2_set_sa_lifetime_t *mp;
12935   int ret;
12936   u8 *name = 0;
12937   u64 lifetime, lifetime_maxdata;
12938   u32 lifetime_jitter, handover;
12939
12940   const char *valid_chars = "a-zA-Z0-9_";
12941
12942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12943     {
12944       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12945                     &lifetime, &lifetime_jitter, &handover,
12946                     &lifetime_maxdata))
12947         vec_add1 (name, 0);
12948       else
12949         {
12950           errmsg ("parse error '%U'", format_unformat_error, i);
12951           return -99;
12952         }
12953     }
12954
12955   if (!vec_len (name))
12956     {
12957       errmsg ("profile name must be specified");
12958       return -99;
12959     }
12960
12961   if (vec_len (name) > 64)
12962     {
12963       errmsg ("profile name too long");
12964       return -99;
12965     }
12966
12967   M (IKEV2_SET_SA_LIFETIME, mp);
12968
12969   clib_memcpy (mp->name, name, vec_len (name));
12970   vec_free (name);
12971   mp->lifetime = lifetime;
12972   mp->lifetime_jitter = lifetime_jitter;
12973   mp->handover = handover;
12974   mp->lifetime_maxdata = lifetime_maxdata;
12975
12976   S (mp);
12977   W (ret);
12978   return ret;
12979 }
12980
12981 static int
12982 api_ikev2_initiate_sa_init (vat_main_t * vam)
12983 {
12984   unformat_input_t *i = vam->input;
12985   vl_api_ikev2_initiate_sa_init_t *mp;
12986   int ret;
12987   u8 *name = 0;
12988
12989   const char *valid_chars = "a-zA-Z0-9_";
12990
12991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12992     {
12993       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12994         vec_add1 (name, 0);
12995       else
12996         {
12997           errmsg ("parse error '%U'", format_unformat_error, i);
12998           return -99;
12999         }
13000     }
13001
13002   if (!vec_len (name))
13003     {
13004       errmsg ("profile name must be specified");
13005       return -99;
13006     }
13007
13008   if (vec_len (name) > 64)
13009     {
13010       errmsg ("profile name too long");
13011       return -99;
13012     }
13013
13014   M (IKEV2_INITIATE_SA_INIT, mp);
13015
13016   clib_memcpy (mp->name, name, vec_len (name));
13017   vec_free (name);
13018
13019   S (mp);
13020   W (ret);
13021   return ret;
13022 }
13023
13024 static int
13025 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13026 {
13027   unformat_input_t *i = vam->input;
13028   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13029   int ret;
13030   u64 ispi;
13031
13032
13033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13034     {
13035       if (unformat (i, "%lx", &ispi))
13036         ;
13037       else
13038         {
13039           errmsg ("parse error '%U'", format_unformat_error, i);
13040           return -99;
13041         }
13042     }
13043
13044   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13045
13046   mp->ispi = ispi;
13047
13048   S (mp);
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13055 {
13056   unformat_input_t *i = vam->input;
13057   vl_api_ikev2_initiate_del_child_sa_t *mp;
13058   int ret;
13059   u32 ispi;
13060
13061
13062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (i, "%x", &ispi))
13065         ;
13066       else
13067         {
13068           errmsg ("parse error '%U'", format_unformat_error, i);
13069           return -99;
13070         }
13071     }
13072
13073   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13074
13075   mp->ispi = ispi;
13076
13077   S (mp);
13078   W (ret);
13079   return ret;
13080 }
13081
13082 static int
13083 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13084 {
13085   unformat_input_t *i = vam->input;
13086   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13087   int ret;
13088   u32 ispi;
13089
13090
13091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13092     {
13093       if (unformat (i, "%x", &ispi))
13094         ;
13095       else
13096         {
13097           errmsg ("parse error '%U'", format_unformat_error, i);
13098           return -99;
13099         }
13100     }
13101
13102   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13103
13104   mp->ispi = ispi;
13105
13106   S (mp);
13107   W (ret);
13108   return ret;
13109 }
13110
13111 /*
13112  * MAP
13113  */
13114 static int
13115 api_map_add_domain (vat_main_t * vam)
13116 {
13117   unformat_input_t *i = vam->input;
13118   vl_api_map_add_domain_t *mp;
13119
13120   ip4_address_t ip4_prefix;
13121   ip6_address_t ip6_prefix;
13122   ip6_address_t ip6_src;
13123   u32 num_m_args = 0;
13124   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13125     0, psid_length = 0;
13126   u8 is_translation = 0;
13127   u32 mtu = 0;
13128   u32 ip6_src_len = 128;
13129   int ret;
13130
13131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13132     {
13133       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13134                     &ip4_prefix, &ip4_prefix_len))
13135         num_m_args++;
13136       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13137                          &ip6_prefix, &ip6_prefix_len))
13138         num_m_args++;
13139       else
13140         if (unformat
13141             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13142              &ip6_src_len))
13143         num_m_args++;
13144       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13145         num_m_args++;
13146       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13147         num_m_args++;
13148       else if (unformat (i, "psid-offset %d", &psid_offset))
13149         num_m_args++;
13150       else if (unformat (i, "psid-len %d", &psid_length))
13151         num_m_args++;
13152       else if (unformat (i, "mtu %d", &mtu))
13153         num_m_args++;
13154       else if (unformat (i, "map-t"))
13155         is_translation = 1;
13156       else
13157         {
13158           clib_warning ("parse error '%U'", format_unformat_error, i);
13159           return -99;
13160         }
13161     }
13162
13163   if (num_m_args < 3)
13164     {
13165       errmsg ("mandatory argument(s) missing");
13166       return -99;
13167     }
13168
13169   /* Construct the API message */
13170   M (MAP_ADD_DOMAIN, mp);
13171
13172   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13173   mp->ip4_prefix_len = ip4_prefix_len;
13174
13175   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13176   mp->ip6_prefix_len = ip6_prefix_len;
13177
13178   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13179   mp->ip6_src_prefix_len = ip6_src_len;
13180
13181   mp->ea_bits_len = ea_bits_len;
13182   mp->psid_offset = psid_offset;
13183   mp->psid_length = psid_length;
13184   mp->is_translation = is_translation;
13185   mp->mtu = htons (mtu);
13186
13187   /* send it... */
13188   S (mp);
13189
13190   /* Wait for a reply, return good/bad news  */
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_map_del_domain (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_map_del_domain_t *mp;
13200
13201   u32 num_m_args = 0;
13202   u32 index;
13203   int ret;
13204
13205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13206     {
13207       if (unformat (i, "index %d", &index))
13208         num_m_args++;
13209       else
13210         {
13211           clib_warning ("parse error '%U'", format_unformat_error, i);
13212           return -99;
13213         }
13214     }
13215
13216   if (num_m_args != 1)
13217     {
13218       errmsg ("mandatory argument(s) missing");
13219       return -99;
13220     }
13221
13222   /* Construct the API message */
13223   M (MAP_DEL_DOMAIN, mp);
13224
13225   mp->index = ntohl (index);
13226
13227   /* send it... */
13228   S (mp);
13229
13230   /* Wait for a reply, return good/bad news  */
13231   W (ret);
13232   return ret;
13233 }
13234
13235 static int
13236 api_map_add_del_rule (vat_main_t * vam)
13237 {
13238   unformat_input_t *i = vam->input;
13239   vl_api_map_add_del_rule_t *mp;
13240   u8 is_add = 1;
13241   ip6_address_t ip6_dst;
13242   u32 num_m_args = 0, index, psid = 0;
13243   int ret;
13244
13245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13246     {
13247       if (unformat (i, "index %d", &index))
13248         num_m_args++;
13249       else if (unformat (i, "psid %d", &psid))
13250         num_m_args++;
13251       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13252         num_m_args++;
13253       else if (unformat (i, "del"))
13254         {
13255           is_add = 0;
13256         }
13257       else
13258         {
13259           clib_warning ("parse error '%U'", format_unformat_error, i);
13260           return -99;
13261         }
13262     }
13263
13264   /* Construct the API message */
13265   M (MAP_ADD_DEL_RULE, mp);
13266
13267   mp->index = ntohl (index);
13268   mp->is_add = is_add;
13269   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13270   mp->psid = ntohs (psid);
13271
13272   /* send it... */
13273   S (mp);
13274
13275   /* Wait for a reply, return good/bad news  */
13276   W (ret);
13277   return ret;
13278 }
13279
13280 static int
13281 api_map_domain_dump (vat_main_t * vam)
13282 {
13283   vl_api_map_domain_dump_t *mp;
13284   vl_api_control_ping_t *mp_ping;
13285   int ret;
13286
13287   /* Construct the API message */
13288   M (MAP_DOMAIN_DUMP, mp);
13289
13290   /* send it... */
13291   S (mp);
13292
13293   /* Use a control ping for synchronization */
13294   M (CONTROL_PING, mp_ping);
13295   S (mp_ping);
13296
13297   W (ret);
13298   return ret;
13299 }
13300
13301 static int
13302 api_map_rule_dump (vat_main_t * vam)
13303 {
13304   unformat_input_t *i = vam->input;
13305   vl_api_map_rule_dump_t *mp;
13306   vl_api_control_ping_t *mp_ping;
13307   u32 domain_index = ~0;
13308   int ret;
13309
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "index %u", &domain_index))
13313         ;
13314       else
13315         break;
13316     }
13317
13318   if (domain_index == ~0)
13319     {
13320       clib_warning ("parse error: domain index expected");
13321       return -99;
13322     }
13323
13324   /* Construct the API message */
13325   M (MAP_RULE_DUMP, mp);
13326
13327   mp->domain_index = htonl (domain_index);
13328
13329   /* send it... */
13330   S (mp);
13331
13332   /* Use a control ping for synchronization */
13333   M (CONTROL_PING, mp_ping);
13334   S (mp_ping);
13335
13336   W (ret);
13337   return ret;
13338 }
13339
13340 static void vl_api_map_add_domain_reply_t_handler
13341   (vl_api_map_add_domain_reply_t * mp)
13342 {
13343   vat_main_t *vam = &vat_main;
13344   i32 retval = ntohl (mp->retval);
13345
13346   if (vam->async_mode)
13347     {
13348       vam->async_errors += (retval < 0);
13349     }
13350   else
13351     {
13352       vam->retval = retval;
13353       vam->result_ready = 1;
13354     }
13355 }
13356
13357 static void vl_api_map_add_domain_reply_t_handler_json
13358   (vl_api_map_add_domain_reply_t * mp)
13359 {
13360   vat_main_t *vam = &vat_main;
13361   vat_json_node_t node;
13362
13363   vat_json_init_object (&node);
13364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13365   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13366
13367   vat_json_print (vam->ofp, &node);
13368   vat_json_free (&node);
13369
13370   vam->retval = ntohl (mp->retval);
13371   vam->result_ready = 1;
13372 }
13373
13374 static int
13375 api_get_first_msg_id (vat_main_t * vam)
13376 {
13377   vl_api_get_first_msg_id_t *mp;
13378   unformat_input_t *i = vam->input;
13379   u8 *name;
13380   u8 name_set = 0;
13381   int ret;
13382
13383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13384     {
13385       if (unformat (i, "client %s", &name))
13386         name_set = 1;
13387       else
13388         break;
13389     }
13390
13391   if (name_set == 0)
13392     {
13393       errmsg ("missing client name");
13394       return -99;
13395     }
13396   vec_add1 (name, 0);
13397
13398   if (vec_len (name) > 63)
13399     {
13400       errmsg ("client name too long");
13401       return -99;
13402     }
13403
13404   M (GET_FIRST_MSG_ID, mp);
13405   clib_memcpy (mp->name, name, vec_len (name));
13406   S (mp);
13407   W (ret);
13408   return ret;
13409 }
13410
13411 static int
13412 api_cop_interface_enable_disable (vat_main_t * vam)
13413 {
13414   unformat_input_t *line_input = vam->input;
13415   vl_api_cop_interface_enable_disable_t *mp;
13416   u32 sw_if_index = ~0;
13417   u8 enable_disable = 1;
13418   int ret;
13419
13420   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13421     {
13422       if (unformat (line_input, "disable"))
13423         enable_disable = 0;
13424       if (unformat (line_input, "enable"))
13425         enable_disable = 1;
13426       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13427                          vam, &sw_if_index))
13428         ;
13429       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13430         ;
13431       else
13432         break;
13433     }
13434
13435   if (sw_if_index == ~0)
13436     {
13437       errmsg ("missing interface name or sw_if_index");
13438       return -99;
13439     }
13440
13441   /* Construct the API message */
13442   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13443   mp->sw_if_index = ntohl (sw_if_index);
13444   mp->enable_disable = enable_disable;
13445
13446   /* send it... */
13447   S (mp);
13448   /* Wait for the reply */
13449   W (ret);
13450   return ret;
13451 }
13452
13453 static int
13454 api_cop_whitelist_enable_disable (vat_main_t * vam)
13455 {
13456   unformat_input_t *line_input = vam->input;
13457   vl_api_cop_whitelist_enable_disable_t *mp;
13458   u32 sw_if_index = ~0;
13459   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13460   u32 fib_id = 0;
13461   int ret;
13462
13463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (line_input, "ip4"))
13466         ip4 = 1;
13467       else if (unformat (line_input, "ip6"))
13468         ip6 = 1;
13469       else if (unformat (line_input, "default"))
13470         default_cop = 1;
13471       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13472                          vam, &sw_if_index))
13473         ;
13474       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13475         ;
13476       else if (unformat (line_input, "fib-id %d", &fib_id))
13477         ;
13478       else
13479         break;
13480     }
13481
13482   if (sw_if_index == ~0)
13483     {
13484       errmsg ("missing interface name or sw_if_index");
13485       return -99;
13486     }
13487
13488   /* Construct the API message */
13489   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13490   mp->sw_if_index = ntohl (sw_if_index);
13491   mp->fib_id = ntohl (fib_id);
13492   mp->ip4 = ip4;
13493   mp->ip6 = ip6;
13494   mp->default_cop = default_cop;
13495
13496   /* send it... */
13497   S (mp);
13498   /* Wait for the reply */
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static int
13504 api_get_node_graph (vat_main_t * vam)
13505 {
13506   vl_api_get_node_graph_t *mp;
13507   int ret;
13508
13509   M (GET_NODE_GRAPH, mp);
13510
13511   /* send it... */
13512   S (mp);
13513   /* Wait for the reply */
13514   W (ret);
13515   return ret;
13516 }
13517
13518 /* *INDENT-OFF* */
13519 /** Used for parsing LISP eids */
13520 typedef CLIB_PACKED(struct{
13521   u8 addr[16];   /**< eid address */
13522   u32 len;       /**< prefix length if IP */
13523   u8 type;      /**< type of eid */
13524 }) lisp_eid_vat_t;
13525 /* *INDENT-ON* */
13526
13527 static uword
13528 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13529 {
13530   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13531
13532   memset (a, 0, sizeof (a[0]));
13533
13534   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13535     {
13536       a->type = 0;              /* ipv4 type */
13537     }
13538   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13539     {
13540       a->type = 1;              /* ipv6 type */
13541     }
13542   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13543     {
13544       a->type = 2;              /* mac type */
13545     }
13546   else
13547     {
13548       return 0;
13549     }
13550
13551   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13552     {
13553       return 0;
13554     }
13555
13556   return 1;
13557 }
13558
13559 static int
13560 lisp_eid_size_vat (u8 type)
13561 {
13562   switch (type)
13563     {
13564     case 0:
13565       return 4;
13566     case 1:
13567       return 16;
13568     case 2:
13569       return 6;
13570     }
13571   return 0;
13572 }
13573
13574 static void
13575 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13576 {
13577   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13578 }
13579
13580 static int
13581 api_one_add_del_locator_set (vat_main_t * vam)
13582 {
13583   unformat_input_t *input = vam->input;
13584   vl_api_one_add_del_locator_set_t *mp;
13585   u8 is_add = 1;
13586   u8 *locator_set_name = NULL;
13587   u8 locator_set_name_set = 0;
13588   vl_api_local_locator_t locator, *locators = 0;
13589   u32 sw_if_index, priority, weight;
13590   u32 data_len = 0;
13591
13592   int ret;
13593   /* Parse args required to build the message */
13594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13595     {
13596       if (unformat (input, "del"))
13597         {
13598           is_add = 0;
13599         }
13600       else if (unformat (input, "locator-set %s", &locator_set_name))
13601         {
13602           locator_set_name_set = 1;
13603         }
13604       else if (unformat (input, "sw_if_index %u p %u w %u",
13605                          &sw_if_index, &priority, &weight))
13606         {
13607           locator.sw_if_index = htonl (sw_if_index);
13608           locator.priority = priority;
13609           locator.weight = weight;
13610           vec_add1 (locators, locator);
13611         }
13612       else
13613         if (unformat
13614             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13615              &sw_if_index, &priority, &weight))
13616         {
13617           locator.sw_if_index = htonl (sw_if_index);
13618           locator.priority = priority;
13619           locator.weight = weight;
13620           vec_add1 (locators, locator);
13621         }
13622       else
13623         break;
13624     }
13625
13626   if (locator_set_name_set == 0)
13627     {
13628       errmsg ("missing locator-set name");
13629       vec_free (locators);
13630       return -99;
13631     }
13632
13633   if (vec_len (locator_set_name) > 64)
13634     {
13635       errmsg ("locator-set name too long");
13636       vec_free (locator_set_name);
13637       vec_free (locators);
13638       return -99;
13639     }
13640   vec_add1 (locator_set_name, 0);
13641
13642   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13643
13644   /* Construct the API message */
13645   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13646
13647   mp->is_add = is_add;
13648   clib_memcpy (mp->locator_set_name, locator_set_name,
13649                vec_len (locator_set_name));
13650   vec_free (locator_set_name);
13651
13652   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13653   if (locators)
13654     clib_memcpy (mp->locators, locators, data_len);
13655   vec_free (locators);
13656
13657   /* send it... */
13658   S (mp);
13659
13660   /* Wait for a reply... */
13661   W (ret);
13662   return ret;
13663 }
13664
13665 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13666
13667 static int
13668 api_one_add_del_locator (vat_main_t * vam)
13669 {
13670   unformat_input_t *input = vam->input;
13671   vl_api_one_add_del_locator_t *mp;
13672   u32 tmp_if_index = ~0;
13673   u32 sw_if_index = ~0;
13674   u8 sw_if_index_set = 0;
13675   u8 sw_if_index_if_name_set = 0;
13676   u32 priority = ~0;
13677   u8 priority_set = 0;
13678   u32 weight = ~0;
13679   u8 weight_set = 0;
13680   u8 is_add = 1;
13681   u8 *locator_set_name = NULL;
13682   u8 locator_set_name_set = 0;
13683   int ret;
13684
13685   /* Parse args required to build the message */
13686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (input, "del"))
13689         {
13690           is_add = 0;
13691         }
13692       else if (unformat (input, "locator-set %s", &locator_set_name))
13693         {
13694           locator_set_name_set = 1;
13695         }
13696       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13697                          &tmp_if_index))
13698         {
13699           sw_if_index_if_name_set = 1;
13700           sw_if_index = tmp_if_index;
13701         }
13702       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13703         {
13704           sw_if_index_set = 1;
13705           sw_if_index = tmp_if_index;
13706         }
13707       else if (unformat (input, "p %d", &priority))
13708         {
13709           priority_set = 1;
13710         }
13711       else if (unformat (input, "w %d", &weight))
13712         {
13713           weight_set = 1;
13714         }
13715       else
13716         break;
13717     }
13718
13719   if (locator_set_name_set == 0)
13720     {
13721       errmsg ("missing locator-set name");
13722       return -99;
13723     }
13724
13725   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13726     {
13727       errmsg ("missing sw_if_index");
13728       vec_free (locator_set_name);
13729       return -99;
13730     }
13731
13732   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13733     {
13734       errmsg ("cannot use both params interface name and sw_if_index");
13735       vec_free (locator_set_name);
13736       return -99;
13737     }
13738
13739   if (priority_set == 0)
13740     {
13741       errmsg ("missing locator-set priority");
13742       vec_free (locator_set_name);
13743       return -99;
13744     }
13745
13746   if (weight_set == 0)
13747     {
13748       errmsg ("missing locator-set weight");
13749       vec_free (locator_set_name);
13750       return -99;
13751     }
13752
13753   if (vec_len (locator_set_name) > 64)
13754     {
13755       errmsg ("locator-set name too long");
13756       vec_free (locator_set_name);
13757       return -99;
13758     }
13759   vec_add1 (locator_set_name, 0);
13760
13761   /* Construct the API message */
13762   M (ONE_ADD_DEL_LOCATOR, mp);
13763
13764   mp->is_add = is_add;
13765   mp->sw_if_index = ntohl (sw_if_index);
13766   mp->priority = priority;
13767   mp->weight = weight;
13768   clib_memcpy (mp->locator_set_name, locator_set_name,
13769                vec_len (locator_set_name));
13770   vec_free (locator_set_name);
13771
13772   /* send it... */
13773   S (mp);
13774
13775   /* Wait for a reply... */
13776   W (ret);
13777   return ret;
13778 }
13779
13780 #define api_lisp_add_del_locator api_one_add_del_locator
13781
13782 uword
13783 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13784 {
13785   u32 *key_id = va_arg (*args, u32 *);
13786   u8 *s = 0;
13787
13788   if (unformat (input, "%s", &s))
13789     {
13790       if (!strcmp ((char *) s, "sha1"))
13791         key_id[0] = HMAC_SHA_1_96;
13792       else if (!strcmp ((char *) s, "sha256"))
13793         key_id[0] = HMAC_SHA_256_128;
13794       else
13795         {
13796           clib_warning ("invalid key_id: '%s'", s);
13797           key_id[0] = HMAC_NO_KEY;
13798         }
13799     }
13800   else
13801     return 0;
13802
13803   vec_free (s);
13804   return 1;
13805 }
13806
13807 static int
13808 api_one_add_del_local_eid (vat_main_t * vam)
13809 {
13810   unformat_input_t *input = vam->input;
13811   vl_api_one_add_del_local_eid_t *mp;
13812   u8 is_add = 1;
13813   u8 eid_set = 0;
13814   lisp_eid_vat_t _eid, *eid = &_eid;
13815   u8 *locator_set_name = 0;
13816   u8 locator_set_name_set = 0;
13817   u32 vni = 0;
13818   u16 key_id = 0;
13819   u8 *key = 0;
13820   int ret;
13821
13822   /* Parse args required to build the message */
13823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13824     {
13825       if (unformat (input, "del"))
13826         {
13827           is_add = 0;
13828         }
13829       else if (unformat (input, "vni %d", &vni))
13830         {
13831           ;
13832         }
13833       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13834         {
13835           eid_set = 1;
13836         }
13837       else if (unformat (input, "locator-set %s", &locator_set_name))
13838         {
13839           locator_set_name_set = 1;
13840         }
13841       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13842         ;
13843       else if (unformat (input, "secret-key %_%v%_", &key))
13844         ;
13845       else
13846         break;
13847     }
13848
13849   if (locator_set_name_set == 0)
13850     {
13851       errmsg ("missing locator-set name");
13852       return -99;
13853     }
13854
13855   if (0 == eid_set)
13856     {
13857       errmsg ("EID address not set!");
13858       vec_free (locator_set_name);
13859       return -99;
13860     }
13861
13862   if (key && (0 == key_id))
13863     {
13864       errmsg ("invalid key_id!");
13865       return -99;
13866     }
13867
13868   if (vec_len (key) > 64)
13869     {
13870       errmsg ("key too long");
13871       vec_free (key);
13872       return -99;
13873     }
13874
13875   if (vec_len (locator_set_name) > 64)
13876     {
13877       errmsg ("locator-set name too long");
13878       vec_free (locator_set_name);
13879       return -99;
13880     }
13881   vec_add1 (locator_set_name, 0);
13882
13883   /* Construct the API message */
13884   M (ONE_ADD_DEL_LOCAL_EID, mp);
13885
13886   mp->is_add = is_add;
13887   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13888   mp->eid_type = eid->type;
13889   mp->prefix_len = eid->len;
13890   mp->vni = clib_host_to_net_u32 (vni);
13891   mp->key_id = clib_host_to_net_u16 (key_id);
13892   clib_memcpy (mp->locator_set_name, locator_set_name,
13893                vec_len (locator_set_name));
13894   clib_memcpy (mp->key, key, vec_len (key));
13895
13896   vec_free (locator_set_name);
13897   vec_free (key);
13898
13899   /* send it... */
13900   S (mp);
13901
13902   /* Wait for a reply... */
13903   W (ret);
13904   return ret;
13905 }
13906
13907 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13908
13909 static int
13910 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13911 {
13912   u32 dp_table = 0, vni = 0;;
13913   unformat_input_t *input = vam->input;
13914   vl_api_gpe_add_del_fwd_entry_t *mp;
13915   u8 is_add = 1;
13916   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13917   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13918   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13919   u32 action = ~0, w;
13920   ip4_address_t rmt_rloc4, lcl_rloc4;
13921   ip6_address_t rmt_rloc6, lcl_rloc6;
13922   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13923   int ret;
13924
13925   memset (&rloc, 0, sizeof (rloc));
13926
13927   /* Parse args required to build the message */
13928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (input, "del"))
13931         is_add = 0;
13932       else if (unformat (input, "add"))
13933         is_add = 1;
13934       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13935         {
13936           rmt_eid_set = 1;
13937         }
13938       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13939         {
13940           lcl_eid_set = 1;
13941         }
13942       else if (unformat (input, "vrf %d", &dp_table))
13943         ;
13944       else if (unformat (input, "bd %d", &dp_table))
13945         ;
13946       else if (unformat (input, "vni %d", &vni))
13947         ;
13948       else if (unformat (input, "w %d", &w))
13949         {
13950           if (!curr_rloc)
13951             {
13952               errmsg ("No RLOC configured for setting priority/weight!");
13953               return -99;
13954             }
13955           curr_rloc->weight = w;
13956         }
13957       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13958                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13959         {
13960           rloc.is_ip4 = 1;
13961
13962           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13963           rloc.weight = 0;
13964           vec_add1 (lcl_locs, rloc);
13965
13966           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13967           vec_add1 (rmt_locs, rloc);
13968           /* weight saved in rmt loc */
13969           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13970         }
13971       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13972                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13973         {
13974           rloc.is_ip4 = 0;
13975           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13976           rloc.weight = 0;
13977           vec_add1 (lcl_locs, rloc);
13978
13979           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13980           vec_add1 (rmt_locs, rloc);
13981           /* weight saved in rmt loc */
13982           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13983         }
13984       else if (unformat (input, "action %d", &action))
13985         {
13986           ;
13987         }
13988       else
13989         {
13990           clib_warning ("parse error '%U'", format_unformat_error, input);
13991           return -99;
13992         }
13993     }
13994
13995   if (!rmt_eid_set)
13996     {
13997       errmsg ("remote eid addresses not set");
13998       return -99;
13999     }
14000
14001   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14002     {
14003       errmsg ("eid types don't match");
14004       return -99;
14005     }
14006
14007   if (0 == rmt_locs && (u32) ~ 0 == action)
14008     {
14009       errmsg ("action not set for negative mapping");
14010       return -99;
14011     }
14012
14013   /* Construct the API message */
14014   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14015       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14016
14017   mp->is_add = is_add;
14018   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14019   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14020   mp->eid_type = rmt_eid->type;
14021   mp->dp_table = clib_host_to_net_u32 (dp_table);
14022   mp->vni = clib_host_to_net_u32 (vni);
14023   mp->rmt_len = rmt_eid->len;
14024   mp->lcl_len = lcl_eid->len;
14025   mp->action = action;
14026
14027   if (0 != rmt_locs && 0 != lcl_locs)
14028     {
14029       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14030       clib_memcpy (mp->locs, lcl_locs,
14031                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14032
14033       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14034       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14035                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14036     }
14037   vec_free (lcl_locs);
14038   vec_free (rmt_locs);
14039
14040   /* send it... */
14041   S (mp);
14042
14043   /* Wait for a reply... */
14044   W (ret);
14045   return ret;
14046 }
14047
14048 static int
14049 api_one_add_del_map_server (vat_main_t * vam)
14050 {
14051   unformat_input_t *input = vam->input;
14052   vl_api_one_add_del_map_server_t *mp;
14053   u8 is_add = 1;
14054   u8 ipv4_set = 0;
14055   u8 ipv6_set = 0;
14056   ip4_address_t ipv4;
14057   ip6_address_t ipv6;
14058   int ret;
14059
14060   /* Parse args required to build the message */
14061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14062     {
14063       if (unformat (input, "del"))
14064         {
14065           is_add = 0;
14066         }
14067       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14068         {
14069           ipv4_set = 1;
14070         }
14071       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14072         {
14073           ipv6_set = 1;
14074         }
14075       else
14076         break;
14077     }
14078
14079   if (ipv4_set && ipv6_set)
14080     {
14081       errmsg ("both eid v4 and v6 addresses set");
14082       return -99;
14083     }
14084
14085   if (!ipv4_set && !ipv6_set)
14086     {
14087       errmsg ("eid addresses not set");
14088       return -99;
14089     }
14090
14091   /* Construct the API message */
14092   M (ONE_ADD_DEL_MAP_SERVER, mp);
14093
14094   mp->is_add = is_add;
14095   if (ipv6_set)
14096     {
14097       mp->is_ipv6 = 1;
14098       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14099     }
14100   else
14101     {
14102       mp->is_ipv6 = 0;
14103       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14104     }
14105
14106   /* send it... */
14107   S (mp);
14108
14109   /* Wait for a reply... */
14110   W (ret);
14111   return ret;
14112 }
14113
14114 #define api_lisp_add_del_map_server api_one_add_del_map_server
14115
14116 static int
14117 api_one_add_del_map_resolver (vat_main_t * vam)
14118 {
14119   unformat_input_t *input = vam->input;
14120   vl_api_one_add_del_map_resolver_t *mp;
14121   u8 is_add = 1;
14122   u8 ipv4_set = 0;
14123   u8 ipv6_set = 0;
14124   ip4_address_t ipv4;
14125   ip6_address_t ipv6;
14126   int ret;
14127
14128   /* Parse args required to build the message */
14129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14130     {
14131       if (unformat (input, "del"))
14132         {
14133           is_add = 0;
14134         }
14135       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14136         {
14137           ipv4_set = 1;
14138         }
14139       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14140         {
14141           ipv6_set = 1;
14142         }
14143       else
14144         break;
14145     }
14146
14147   if (ipv4_set && ipv6_set)
14148     {
14149       errmsg ("both eid v4 and v6 addresses set");
14150       return -99;
14151     }
14152
14153   if (!ipv4_set && !ipv6_set)
14154     {
14155       errmsg ("eid addresses not set");
14156       return -99;
14157     }
14158
14159   /* Construct the API message */
14160   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14161
14162   mp->is_add = is_add;
14163   if (ipv6_set)
14164     {
14165       mp->is_ipv6 = 1;
14166       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14167     }
14168   else
14169     {
14170       mp->is_ipv6 = 0;
14171       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14172     }
14173
14174   /* send it... */
14175   S (mp);
14176
14177   /* Wait for a reply... */
14178   W (ret);
14179   return ret;
14180 }
14181
14182 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14183
14184 static int
14185 api_lisp_gpe_enable_disable (vat_main_t * vam)
14186 {
14187   unformat_input_t *input = vam->input;
14188   vl_api_gpe_enable_disable_t *mp;
14189   u8 is_set = 0;
14190   u8 is_en = 1;
14191   int ret;
14192
14193   /* Parse args required to build the message */
14194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14195     {
14196       if (unformat (input, "enable"))
14197         {
14198           is_set = 1;
14199           is_en = 1;
14200         }
14201       else if (unformat (input, "disable"))
14202         {
14203           is_set = 1;
14204           is_en = 0;
14205         }
14206       else
14207         break;
14208     }
14209
14210   if (is_set == 0)
14211     {
14212       errmsg ("Value not set");
14213       return -99;
14214     }
14215
14216   /* Construct the API message */
14217   M (GPE_ENABLE_DISABLE, mp);
14218
14219   mp->is_en = is_en;
14220
14221   /* send it... */
14222   S (mp);
14223
14224   /* Wait for a reply... */
14225   W (ret);
14226   return ret;
14227 }
14228
14229 static int
14230 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14231 {
14232   unformat_input_t *input = vam->input;
14233   vl_api_one_rloc_probe_enable_disable_t *mp;
14234   u8 is_set = 0;
14235   u8 is_en = 0;
14236   int ret;
14237
14238   /* Parse args required to build the message */
14239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14240     {
14241       if (unformat (input, "enable"))
14242         {
14243           is_set = 1;
14244           is_en = 1;
14245         }
14246       else if (unformat (input, "disable"))
14247         is_set = 1;
14248       else
14249         break;
14250     }
14251
14252   if (!is_set)
14253     {
14254       errmsg ("Value not set");
14255       return -99;
14256     }
14257
14258   /* Construct the API message */
14259   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14260
14261   mp->is_enabled = is_en;
14262
14263   /* send it... */
14264   S (mp);
14265
14266   /* Wait for a reply... */
14267   W (ret);
14268   return ret;
14269 }
14270
14271 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14272
14273 static int
14274 api_one_map_register_enable_disable (vat_main_t * vam)
14275 {
14276   unformat_input_t *input = vam->input;
14277   vl_api_one_map_register_enable_disable_t *mp;
14278   u8 is_set = 0;
14279   u8 is_en = 0;
14280   int ret;
14281
14282   /* Parse args required to build the message */
14283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14284     {
14285       if (unformat (input, "enable"))
14286         {
14287           is_set = 1;
14288           is_en = 1;
14289         }
14290       else if (unformat (input, "disable"))
14291         is_set = 1;
14292       else
14293         break;
14294     }
14295
14296   if (!is_set)
14297     {
14298       errmsg ("Value not set");
14299       return -99;
14300     }
14301
14302   /* Construct the API message */
14303   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14304
14305   mp->is_enabled = is_en;
14306
14307   /* send it... */
14308   S (mp);
14309
14310   /* Wait for a reply... */
14311   W (ret);
14312   return ret;
14313 }
14314
14315 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14316
14317 static int
14318 api_one_enable_disable (vat_main_t * vam)
14319 {
14320   unformat_input_t *input = vam->input;
14321   vl_api_one_enable_disable_t *mp;
14322   u8 is_set = 0;
14323   u8 is_en = 0;
14324   int ret;
14325
14326   /* Parse args required to build the message */
14327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14328     {
14329       if (unformat (input, "enable"))
14330         {
14331           is_set = 1;
14332           is_en = 1;
14333         }
14334       else if (unformat (input, "disable"))
14335         {
14336           is_set = 1;
14337         }
14338       else
14339         break;
14340     }
14341
14342   if (!is_set)
14343     {
14344       errmsg ("Value not set");
14345       return -99;
14346     }
14347
14348   /* Construct the API message */
14349   M (ONE_ENABLE_DISABLE, mp);
14350
14351   mp->is_en = is_en;
14352
14353   /* send it... */
14354   S (mp);
14355
14356   /* Wait for a reply... */
14357   W (ret);
14358   return ret;
14359 }
14360
14361 #define api_lisp_enable_disable api_one_enable_disable
14362
14363 static int
14364 api_show_one_map_register_state (vat_main_t * vam)
14365 {
14366   vl_api_show_one_map_register_state_t *mp;
14367   int ret;
14368
14369   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14370
14371   /* send */
14372   S (mp);
14373
14374   /* wait for reply */
14375   W (ret);
14376   return ret;
14377 }
14378
14379 #define api_show_lisp_map_register_state api_show_one_map_register_state
14380
14381 static int
14382 api_show_one_rloc_probe_state (vat_main_t * vam)
14383 {
14384   vl_api_show_one_rloc_probe_state_t *mp;
14385   int ret;
14386
14387   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14388
14389   /* send */
14390   S (mp);
14391
14392   /* wait for reply */
14393   W (ret);
14394   return ret;
14395 }
14396
14397 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14398
14399 static int
14400 api_show_one_map_request_mode (vat_main_t * vam)
14401 {
14402   vl_api_show_one_map_request_mode_t *mp;
14403   int ret;
14404
14405   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14406
14407   /* send */
14408   S (mp);
14409
14410   /* wait for reply */
14411   W (ret);
14412   return ret;
14413 }
14414
14415 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14416
14417 static int
14418 api_one_map_request_mode (vat_main_t * vam)
14419 {
14420   unformat_input_t *input = vam->input;
14421   vl_api_one_map_request_mode_t *mp;
14422   u8 mode = 0;
14423   int ret;
14424
14425   /* Parse args required to build the message */
14426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14427     {
14428       if (unformat (input, "dst-only"))
14429         mode = 0;
14430       else if (unformat (input, "src-dst"))
14431         mode = 1;
14432       else
14433         {
14434           errmsg ("parse error '%U'", format_unformat_error, input);
14435           return -99;
14436         }
14437     }
14438
14439   M (ONE_MAP_REQUEST_MODE, mp);
14440
14441   mp->mode = mode;
14442
14443   /* send */
14444   S (mp);
14445
14446   /* wait for reply */
14447   W (ret);
14448   return ret;
14449 }
14450
14451 #define api_lisp_map_request_mode api_one_map_request_mode
14452
14453 /**
14454  * Enable/disable ONE proxy ITR.
14455  *
14456  * @param vam vpp API test context
14457  * @return return code
14458  */
14459 static int
14460 api_one_pitr_set_locator_set (vat_main_t * vam)
14461 {
14462   u8 ls_name_set = 0;
14463   unformat_input_t *input = vam->input;
14464   vl_api_one_pitr_set_locator_set_t *mp;
14465   u8 is_add = 1;
14466   u8 *ls_name = 0;
14467   int ret;
14468
14469   /* Parse args required to build the message */
14470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14471     {
14472       if (unformat (input, "del"))
14473         is_add = 0;
14474       else if (unformat (input, "locator-set %s", &ls_name))
14475         ls_name_set = 1;
14476       else
14477         {
14478           errmsg ("parse error '%U'", format_unformat_error, input);
14479           return -99;
14480         }
14481     }
14482
14483   if (!ls_name_set)
14484     {
14485       errmsg ("locator-set name not set!");
14486       return -99;
14487     }
14488
14489   M (ONE_PITR_SET_LOCATOR_SET, mp);
14490
14491   mp->is_add = is_add;
14492   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14493   vec_free (ls_name);
14494
14495   /* send */
14496   S (mp);
14497
14498   /* wait for reply */
14499   W (ret);
14500   return ret;
14501 }
14502
14503 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14504
14505 static int
14506 api_show_one_pitr (vat_main_t * vam)
14507 {
14508   vl_api_show_one_pitr_t *mp;
14509   int ret;
14510
14511   if (!vam->json_output)
14512     {
14513       print (vam->ofp, "%=20s", "lisp status:");
14514     }
14515
14516   M (SHOW_ONE_PITR, mp);
14517   /* send it... */
14518   S (mp);
14519
14520   /* Wait for a reply... */
14521   W (ret);
14522   return ret;
14523 }
14524
14525 #define api_show_lisp_pitr api_show_one_pitr
14526
14527 /**
14528  * Add/delete mapping between vni and vrf
14529  */
14530 static int
14531 api_one_eid_table_add_del_map (vat_main_t * vam)
14532 {
14533   unformat_input_t *input = vam->input;
14534   vl_api_one_eid_table_add_del_map_t *mp;
14535   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14536   u32 vni, vrf, bd_index;
14537   int ret;
14538
14539   /* Parse args required to build the message */
14540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14541     {
14542       if (unformat (input, "del"))
14543         is_add = 0;
14544       else if (unformat (input, "vrf %d", &vrf))
14545         vrf_set = 1;
14546       else if (unformat (input, "bd_index %d", &bd_index))
14547         bd_index_set = 1;
14548       else if (unformat (input, "vni %d", &vni))
14549         vni_set = 1;
14550       else
14551         break;
14552     }
14553
14554   if (!vni_set || (!vrf_set && !bd_index_set))
14555     {
14556       errmsg ("missing arguments!");
14557       return -99;
14558     }
14559
14560   if (vrf_set && bd_index_set)
14561     {
14562       errmsg ("error: both vrf and bd entered!");
14563       return -99;
14564     }
14565
14566   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14567
14568   mp->is_add = is_add;
14569   mp->vni = htonl (vni);
14570   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14571   mp->is_l2 = bd_index_set;
14572
14573   /* send */
14574   S (mp);
14575
14576   /* wait for reply */
14577   W (ret);
14578   return ret;
14579 }
14580
14581 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14582
14583 uword
14584 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14585 {
14586   u32 *action = va_arg (*args, u32 *);
14587   u8 *s = 0;
14588
14589   if (unformat (input, "%s", &s))
14590     {
14591       if (!strcmp ((char *) s, "no-action"))
14592         action[0] = 0;
14593       else if (!strcmp ((char *) s, "natively-forward"))
14594         action[0] = 1;
14595       else if (!strcmp ((char *) s, "send-map-request"))
14596         action[0] = 2;
14597       else if (!strcmp ((char *) s, "drop"))
14598         action[0] = 3;
14599       else
14600         {
14601           clib_warning ("invalid action: '%s'", s);
14602           action[0] = 3;
14603         }
14604     }
14605   else
14606     return 0;
14607
14608   vec_free (s);
14609   return 1;
14610 }
14611
14612 /**
14613  * Add/del remote mapping to/from ONE control plane
14614  *
14615  * @param vam vpp API test context
14616  * @return return code
14617  */
14618 static int
14619 api_one_add_del_remote_mapping (vat_main_t * vam)
14620 {
14621   unformat_input_t *input = vam->input;
14622   vl_api_one_add_del_remote_mapping_t *mp;
14623   u32 vni = 0;
14624   lisp_eid_vat_t _eid, *eid = &_eid;
14625   lisp_eid_vat_t _seid, *seid = &_seid;
14626   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14627   u32 action = ~0, p, w, data_len;
14628   ip4_address_t rloc4;
14629   ip6_address_t rloc6;
14630   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14631   int ret;
14632
14633   memset (&rloc, 0, sizeof (rloc));
14634
14635   /* Parse args required to build the message */
14636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (input, "del-all"))
14639         {
14640           del_all = 1;
14641         }
14642       else if (unformat (input, "del"))
14643         {
14644           is_add = 0;
14645         }
14646       else if (unformat (input, "add"))
14647         {
14648           is_add = 1;
14649         }
14650       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14651         {
14652           eid_set = 1;
14653         }
14654       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14655         {
14656           seid_set = 1;
14657         }
14658       else if (unformat (input, "vni %d", &vni))
14659         {
14660           ;
14661         }
14662       else if (unformat (input, "p %d w %d", &p, &w))
14663         {
14664           if (!curr_rloc)
14665             {
14666               errmsg ("No RLOC configured for setting priority/weight!");
14667               return -99;
14668             }
14669           curr_rloc->priority = p;
14670           curr_rloc->weight = w;
14671         }
14672       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14673         {
14674           rloc.is_ip4 = 1;
14675           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14676           vec_add1 (rlocs, rloc);
14677           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14678         }
14679       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14680         {
14681           rloc.is_ip4 = 0;
14682           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14683           vec_add1 (rlocs, rloc);
14684           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14685         }
14686       else if (unformat (input, "action %U",
14687                          unformat_negative_mapping_action, &action))
14688         {
14689           ;
14690         }
14691       else
14692         {
14693           clib_warning ("parse error '%U'", format_unformat_error, input);
14694           return -99;
14695         }
14696     }
14697
14698   if (0 == eid_set)
14699     {
14700       errmsg ("missing params!");
14701       return -99;
14702     }
14703
14704   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14705     {
14706       errmsg ("no action set for negative map-reply!");
14707       return -99;
14708     }
14709
14710   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14711
14712   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14713   mp->is_add = is_add;
14714   mp->vni = htonl (vni);
14715   mp->action = (u8) action;
14716   mp->is_src_dst = seid_set;
14717   mp->eid_len = eid->len;
14718   mp->seid_len = seid->len;
14719   mp->del_all = del_all;
14720   mp->eid_type = eid->type;
14721   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14722   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14723
14724   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14725   clib_memcpy (mp->rlocs, rlocs, data_len);
14726   vec_free (rlocs);
14727
14728   /* send it... */
14729   S (mp);
14730
14731   /* Wait for a reply... */
14732   W (ret);
14733   return ret;
14734 }
14735
14736 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14737
14738 /**
14739  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14740  * forwarding entries in data-plane accordingly.
14741  *
14742  * @param vam vpp API test context
14743  * @return return code
14744  */
14745 static int
14746 api_one_add_del_adjacency (vat_main_t * vam)
14747 {
14748   unformat_input_t *input = vam->input;
14749   vl_api_one_add_del_adjacency_t *mp;
14750   u32 vni = 0;
14751   ip4_address_t leid4, reid4;
14752   ip6_address_t leid6, reid6;
14753   u8 reid_mac[6] = { 0 };
14754   u8 leid_mac[6] = { 0 };
14755   u8 reid_type, leid_type;
14756   u32 leid_len = 0, reid_len = 0, len;
14757   u8 is_add = 1;
14758   int ret;
14759
14760   leid_type = reid_type = (u8) ~ 0;
14761
14762   /* Parse args required to build the message */
14763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14764     {
14765       if (unformat (input, "del"))
14766         {
14767           is_add = 0;
14768         }
14769       else if (unformat (input, "add"))
14770         {
14771           is_add = 1;
14772         }
14773       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14774                          &reid4, &len))
14775         {
14776           reid_type = 0;        /* ipv4 */
14777           reid_len = len;
14778         }
14779       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14780                          &reid6, &len))
14781         {
14782           reid_type = 1;        /* ipv6 */
14783           reid_len = len;
14784         }
14785       else if (unformat (input, "reid %U", unformat_ethernet_address,
14786                          reid_mac))
14787         {
14788           reid_type = 2;        /* mac */
14789         }
14790       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14791                          &leid4, &len))
14792         {
14793           leid_type = 0;        /* ipv4 */
14794           leid_len = len;
14795         }
14796       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14797                          &leid6, &len))
14798         {
14799           leid_type = 1;        /* ipv6 */
14800           leid_len = len;
14801         }
14802       else if (unformat (input, "leid %U", unformat_ethernet_address,
14803                          leid_mac))
14804         {
14805           leid_type = 2;        /* mac */
14806         }
14807       else if (unformat (input, "vni %d", &vni))
14808         {
14809           ;
14810         }
14811       else
14812         {
14813           errmsg ("parse error '%U'", format_unformat_error, input);
14814           return -99;
14815         }
14816     }
14817
14818   if ((u8) ~ 0 == reid_type)
14819     {
14820       errmsg ("missing params!");
14821       return -99;
14822     }
14823
14824   if (leid_type != reid_type)
14825     {
14826       errmsg ("remote and local EIDs are of different types!");
14827       return -99;
14828     }
14829
14830   M (ONE_ADD_DEL_ADJACENCY, mp);
14831   mp->is_add = is_add;
14832   mp->vni = htonl (vni);
14833   mp->leid_len = leid_len;
14834   mp->reid_len = reid_len;
14835   mp->eid_type = reid_type;
14836
14837   switch (mp->eid_type)
14838     {
14839     case 0:
14840       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14841       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14842       break;
14843     case 1:
14844       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14845       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14846       break;
14847     case 2:
14848       clib_memcpy (mp->leid, leid_mac, 6);
14849       clib_memcpy (mp->reid, reid_mac, 6);
14850       break;
14851     default:
14852       errmsg ("unknown EID type %d!", mp->eid_type);
14853       return 0;
14854     }
14855
14856   /* send it... */
14857   S (mp);
14858
14859   /* Wait for a reply... */
14860   W (ret);
14861   return ret;
14862 }
14863
14864 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14865
14866 static int
14867 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14868 {
14869   unformat_input_t *input = vam->input;
14870   vl_api_gpe_add_del_iface_t *mp;
14871   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14872   u32 dp_table = 0, vni = 0;
14873   int ret;
14874
14875   /* Parse args required to build the message */
14876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14877     {
14878       if (unformat (input, "up"))
14879         {
14880           action_set = 1;
14881           is_add = 1;
14882         }
14883       else if (unformat (input, "down"))
14884         {
14885           action_set = 1;
14886           is_add = 0;
14887         }
14888       else if (unformat (input, "table_id %d", &dp_table))
14889         {
14890           dp_table_set = 1;
14891         }
14892       else if (unformat (input, "bd_id %d", &dp_table))
14893         {
14894           dp_table_set = 1;
14895           is_l2 = 1;
14896         }
14897       else if (unformat (input, "vni %d", &vni))
14898         {
14899           vni_set = 1;
14900         }
14901       else
14902         break;
14903     }
14904
14905   if (action_set == 0)
14906     {
14907       errmsg ("Action not set");
14908       return -99;
14909     }
14910   if (dp_table_set == 0 || vni_set == 0)
14911     {
14912       errmsg ("vni and dp_table must be set");
14913       return -99;
14914     }
14915
14916   /* Construct the API message */
14917   M (GPE_ADD_DEL_IFACE, mp);
14918
14919   mp->is_add = is_add;
14920   mp->dp_table = dp_table;
14921   mp->is_l2 = is_l2;
14922   mp->vni = vni;
14923
14924   /* send it... */
14925   S (mp);
14926
14927   /* Wait for a reply... */
14928   W (ret);
14929   return ret;
14930 }
14931
14932 /**
14933  * Add/del map request itr rlocs from ONE control plane and updates
14934  *
14935  * @param vam vpp API test context
14936  * @return return code
14937  */
14938 static int
14939 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14940 {
14941   unformat_input_t *input = vam->input;
14942   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14943   u8 *locator_set_name = 0;
14944   u8 locator_set_name_set = 0;
14945   u8 is_add = 1;
14946   int ret;
14947
14948   /* Parse args required to build the message */
14949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14950     {
14951       if (unformat (input, "del"))
14952         {
14953           is_add = 0;
14954         }
14955       else if (unformat (input, "%_%v%_", &locator_set_name))
14956         {
14957           locator_set_name_set = 1;
14958         }
14959       else
14960         {
14961           clib_warning ("parse error '%U'", format_unformat_error, input);
14962           return -99;
14963         }
14964     }
14965
14966   if (is_add && !locator_set_name_set)
14967     {
14968       errmsg ("itr-rloc is not set!");
14969       return -99;
14970     }
14971
14972   if (is_add && vec_len (locator_set_name) > 64)
14973     {
14974       errmsg ("itr-rloc locator-set name too long");
14975       vec_free (locator_set_name);
14976       return -99;
14977     }
14978
14979   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14980   mp->is_add = is_add;
14981   if (is_add)
14982     {
14983       clib_memcpy (mp->locator_set_name, locator_set_name,
14984                    vec_len (locator_set_name));
14985     }
14986   else
14987     {
14988       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14989     }
14990   vec_free (locator_set_name);
14991
14992   /* send it... */
14993   S (mp);
14994
14995   /* Wait for a reply... */
14996   W (ret);
14997   return ret;
14998 }
14999
15000 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15001
15002 static int
15003 api_one_locator_dump (vat_main_t * vam)
15004 {
15005   unformat_input_t *input = vam->input;
15006   vl_api_one_locator_dump_t *mp;
15007   vl_api_control_ping_t *mp_ping;
15008   u8 is_index_set = 0, is_name_set = 0;
15009   u8 *ls_name = 0;
15010   u32 ls_index = ~0;
15011   int ret;
15012
15013   /* Parse args required to build the message */
15014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15015     {
15016       if (unformat (input, "ls_name %_%v%_", &ls_name))
15017         {
15018           is_name_set = 1;
15019         }
15020       else if (unformat (input, "ls_index %d", &ls_index))
15021         {
15022           is_index_set = 1;
15023         }
15024       else
15025         {
15026           errmsg ("parse error '%U'", format_unformat_error, input);
15027           return -99;
15028         }
15029     }
15030
15031   if (!is_index_set && !is_name_set)
15032     {
15033       errmsg ("error: expected one of index or name!");
15034       return -99;
15035     }
15036
15037   if (is_index_set && is_name_set)
15038     {
15039       errmsg ("error: only one param expected!");
15040       return -99;
15041     }
15042
15043   if (vec_len (ls_name) > 62)
15044     {
15045       errmsg ("error: locator set name too long!");
15046       return -99;
15047     }
15048
15049   if (!vam->json_output)
15050     {
15051       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15052     }
15053
15054   M (ONE_LOCATOR_DUMP, mp);
15055   mp->is_index_set = is_index_set;
15056
15057   if (is_index_set)
15058     mp->ls_index = clib_host_to_net_u32 (ls_index);
15059   else
15060     {
15061       vec_add1 (ls_name, 0);
15062       strncpy ((char *) mp->ls_name, (char *) ls_name,
15063                sizeof (mp->ls_name) - 1);
15064     }
15065
15066   /* send it... */
15067   S (mp);
15068
15069   /* Use a control ping for synchronization */
15070   M (CONTROL_PING, mp_ping);
15071   S (mp_ping);
15072
15073   /* Wait for a reply... */
15074   W (ret);
15075   return ret;
15076 }
15077
15078 #define api_lisp_locator_dump api_one_locator_dump
15079
15080 static int
15081 api_one_locator_set_dump (vat_main_t * vam)
15082 {
15083   vl_api_one_locator_set_dump_t *mp;
15084   vl_api_control_ping_t *mp_ping;
15085   unformat_input_t *input = vam->input;
15086   u8 filter = 0;
15087   int ret;
15088
15089   /* Parse args required to build the message */
15090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15091     {
15092       if (unformat (input, "local"))
15093         {
15094           filter = 1;
15095         }
15096       else if (unformat (input, "remote"))
15097         {
15098           filter = 2;
15099         }
15100       else
15101         {
15102           errmsg ("parse error '%U'", format_unformat_error, input);
15103           return -99;
15104         }
15105     }
15106
15107   if (!vam->json_output)
15108     {
15109       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15110     }
15111
15112   M (ONE_LOCATOR_SET_DUMP, mp);
15113
15114   mp->filter = filter;
15115
15116   /* send it... */
15117   S (mp);
15118
15119   /* Use a control ping for synchronization */
15120   M (CONTROL_PING, mp_ping);
15121   S (mp_ping);
15122
15123   /* Wait for a reply... */
15124   W (ret);
15125   return ret;
15126 }
15127
15128 #define api_lisp_locator_set_dump api_one_locator_set_dump
15129
15130 static int
15131 api_one_eid_table_map_dump (vat_main_t * vam)
15132 {
15133   u8 is_l2 = 0;
15134   u8 mode_set = 0;
15135   unformat_input_t *input = vam->input;
15136   vl_api_one_eid_table_map_dump_t *mp;
15137   vl_api_control_ping_t *mp_ping;
15138   int ret;
15139
15140   /* Parse args required to build the message */
15141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15142     {
15143       if (unformat (input, "l2"))
15144         {
15145           is_l2 = 1;
15146           mode_set = 1;
15147         }
15148       else if (unformat (input, "l3"))
15149         {
15150           is_l2 = 0;
15151           mode_set = 1;
15152         }
15153       else
15154         {
15155           errmsg ("parse error '%U'", format_unformat_error, input);
15156           return -99;
15157         }
15158     }
15159
15160   if (!mode_set)
15161     {
15162       errmsg ("expected one of 'l2' or 'l3' parameter!");
15163       return -99;
15164     }
15165
15166   if (!vam->json_output)
15167     {
15168       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15169     }
15170
15171   M (ONE_EID_TABLE_MAP_DUMP, mp);
15172   mp->is_l2 = is_l2;
15173
15174   /* send it... */
15175   S (mp);
15176
15177   /* Use a control ping for synchronization */
15178   M (CONTROL_PING, mp_ping);
15179   S (mp_ping);
15180
15181   /* Wait for a reply... */
15182   W (ret);
15183   return ret;
15184 }
15185
15186 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15187
15188 static int
15189 api_one_eid_table_vni_dump (vat_main_t * vam)
15190 {
15191   vl_api_one_eid_table_vni_dump_t *mp;
15192   vl_api_control_ping_t *mp_ping;
15193   int ret;
15194
15195   if (!vam->json_output)
15196     {
15197       print (vam->ofp, "VNI");
15198     }
15199
15200   M (ONE_EID_TABLE_VNI_DUMP, mp);
15201
15202   /* send it... */
15203   S (mp);
15204
15205   /* Use a control ping for synchronization */
15206   M (CONTROL_PING, mp_ping);
15207   S (mp_ping);
15208
15209   /* Wait for a reply... */
15210   W (ret);
15211   return ret;
15212 }
15213
15214 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15215
15216 static int
15217 api_one_eid_table_dump (vat_main_t * vam)
15218 {
15219   unformat_input_t *i = vam->input;
15220   vl_api_one_eid_table_dump_t *mp;
15221   vl_api_control_ping_t *mp_ping;
15222   struct in_addr ip4;
15223   struct in6_addr ip6;
15224   u8 mac[6];
15225   u8 eid_type = ~0, eid_set = 0;
15226   u32 prefix_length = ~0, t, vni = 0;
15227   u8 filter = 0;
15228   int ret;
15229
15230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15233         {
15234           eid_set = 1;
15235           eid_type = 0;
15236           prefix_length = t;
15237         }
15238       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15239         {
15240           eid_set = 1;
15241           eid_type = 1;
15242           prefix_length = t;
15243         }
15244       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15245         {
15246           eid_set = 1;
15247           eid_type = 2;
15248         }
15249       else if (unformat (i, "vni %d", &t))
15250         {
15251           vni = t;
15252         }
15253       else if (unformat (i, "local"))
15254         {
15255           filter = 1;
15256         }
15257       else if (unformat (i, "remote"))
15258         {
15259           filter = 2;
15260         }
15261       else
15262         {
15263           errmsg ("parse error '%U'", format_unformat_error, i);
15264           return -99;
15265         }
15266     }
15267
15268   if (!vam->json_output)
15269     {
15270       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15271              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15272     }
15273
15274   M (ONE_EID_TABLE_DUMP, mp);
15275
15276   mp->filter = filter;
15277   if (eid_set)
15278     {
15279       mp->eid_set = 1;
15280       mp->vni = htonl (vni);
15281       mp->eid_type = eid_type;
15282       switch (eid_type)
15283         {
15284         case 0:
15285           mp->prefix_length = prefix_length;
15286           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15287           break;
15288         case 1:
15289           mp->prefix_length = prefix_length;
15290           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15291           break;
15292         case 2:
15293           clib_memcpy (mp->eid, mac, sizeof (mac));
15294           break;
15295         default:
15296           errmsg ("unknown EID type %d!", eid_type);
15297           return -99;
15298         }
15299     }
15300
15301   /* send it... */
15302   S (mp);
15303
15304   /* Use a control ping for synchronization */
15305   M (CONTROL_PING, mp_ping);
15306   S (mp_ping);
15307
15308   /* Wait for a reply... */
15309   W (ret);
15310   return ret;
15311 }
15312
15313 #define api_lisp_eid_table_dump api_one_eid_table_dump
15314
15315 static int
15316 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15317 {
15318   unformat_input_t *i = vam->input;
15319   vl_api_gpe_fwd_entries_get_t *mp;
15320   u8 vni_set = 0;
15321   u32 vni = ~0;
15322   int ret;
15323
15324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15325     {
15326       if (unformat (i, "vni %d", &vni))
15327         {
15328           vni_set = 1;
15329         }
15330       else
15331         {
15332           errmsg ("parse error '%U'", format_unformat_error, i);
15333           return -99;
15334         }
15335     }
15336
15337   if (!vni_set)
15338     {
15339       errmsg ("vni not set!");
15340       return -99;
15341     }
15342
15343   if (!vam->json_output)
15344     {
15345       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15346              "leid", "reid");
15347     }
15348
15349   M (GPE_FWD_ENTRIES_GET, mp);
15350   mp->vni = clib_host_to_net_u32 (vni);
15351
15352   /* send it... */
15353   S (mp);
15354
15355   /* Wait for a reply... */
15356   W (ret);
15357   return ret;
15358 }
15359
15360 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15361 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15362 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15363 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15364
15365 static int
15366 api_one_adjacencies_get (vat_main_t * vam)
15367 {
15368   unformat_input_t *i = vam->input;
15369   vl_api_one_adjacencies_get_t *mp;
15370   u8 vni_set = 0;
15371   u32 vni = ~0;
15372   int ret;
15373
15374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15375     {
15376       if (unformat (i, "vni %d", &vni))
15377         {
15378           vni_set = 1;
15379         }
15380       else
15381         {
15382           errmsg ("parse error '%U'", format_unformat_error, i);
15383           return -99;
15384         }
15385     }
15386
15387   if (!vni_set)
15388     {
15389       errmsg ("vni not set!");
15390       return -99;
15391     }
15392
15393   if (!vam->json_output)
15394     {
15395       print (vam->ofp, "%s %40s", "leid", "reid");
15396     }
15397
15398   M (ONE_ADJACENCIES_GET, mp);
15399   mp->vni = clib_host_to_net_u32 (vni);
15400
15401   /* send it... */
15402   S (mp);
15403
15404   /* Wait for a reply... */
15405   W (ret);
15406   return ret;
15407 }
15408
15409 #define api_lisp_adjacencies_get api_one_adjacencies_get
15410
15411 static int
15412 api_one_map_server_dump (vat_main_t * vam)
15413 {
15414   vl_api_one_map_server_dump_t *mp;
15415   vl_api_control_ping_t *mp_ping;
15416   int ret;
15417
15418   if (!vam->json_output)
15419     {
15420       print (vam->ofp, "%=20s", "Map server");
15421     }
15422
15423   M (ONE_MAP_SERVER_DUMP, mp);
15424   /* send it... */
15425   S (mp);
15426
15427   /* Use a control ping for synchronization */
15428   M (CONTROL_PING, mp_ping);
15429   S (mp_ping);
15430
15431   /* Wait for a reply... */
15432   W (ret);
15433   return ret;
15434 }
15435
15436 #define api_lisp_map_server_dump api_one_map_server_dump
15437
15438 static int
15439 api_one_map_resolver_dump (vat_main_t * vam)
15440 {
15441   vl_api_one_map_resolver_dump_t *mp;
15442   vl_api_control_ping_t *mp_ping;
15443   int ret;
15444
15445   if (!vam->json_output)
15446     {
15447       print (vam->ofp, "%=20s", "Map resolver");
15448     }
15449
15450   M (ONE_MAP_RESOLVER_DUMP, mp);
15451   /* send it... */
15452   S (mp);
15453
15454   /* Use a control ping for synchronization */
15455   M (CONTROL_PING, mp_ping);
15456   S (mp_ping);
15457
15458   /* Wait for a reply... */
15459   W (ret);
15460   return ret;
15461 }
15462
15463 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15464
15465 static int
15466 api_show_one_status (vat_main_t * vam)
15467 {
15468   vl_api_show_one_status_t *mp;
15469   int ret;
15470
15471   if (!vam->json_output)
15472     {
15473       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15474     }
15475
15476   M (SHOW_ONE_STATUS, mp);
15477   /* send it... */
15478   S (mp);
15479   /* Wait for a reply... */
15480   W (ret);
15481   return ret;
15482 }
15483
15484 #define api_show_lisp_status api_show_one_status
15485
15486 static int
15487 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15488 {
15489   vl_api_gpe_fwd_entry_path_dump_t *mp;
15490   vl_api_control_ping_t *mp_ping;
15491   unformat_input_t *i = vam->input;
15492   u32 fwd_entry_index = ~0;
15493   int ret;
15494
15495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15496     {
15497       if (unformat (i, "index %d", &fwd_entry_index))
15498         ;
15499       else
15500         break;
15501     }
15502
15503   if (~0 == fwd_entry_index)
15504     {
15505       errmsg ("no index specified!");
15506       return -99;
15507     }
15508
15509   if (!vam->json_output)
15510     {
15511       print (vam->ofp, "first line");
15512     }
15513
15514   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15515
15516   /* send it... */
15517   S (mp);
15518   /* Use a control ping for synchronization */
15519   M (CONTROL_PING, mp_ping);
15520   S (mp_ping);
15521
15522   /* Wait for a reply... */
15523   W (ret);
15524   return ret;
15525 }
15526
15527 static int
15528 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15529 {
15530   vl_api_one_get_map_request_itr_rlocs_t *mp;
15531   int ret;
15532
15533   if (!vam->json_output)
15534     {
15535       print (vam->ofp, "%=20s", "itr-rlocs:");
15536     }
15537
15538   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15539   /* send it... */
15540   S (mp);
15541   /* Wait for a reply... */
15542   W (ret);
15543   return ret;
15544 }
15545
15546 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15547
15548 static int
15549 api_af_packet_create (vat_main_t * vam)
15550 {
15551   unformat_input_t *i = vam->input;
15552   vl_api_af_packet_create_t *mp;
15553   u8 *host_if_name = 0;
15554   u8 hw_addr[6];
15555   u8 random_hw_addr = 1;
15556   int ret;
15557
15558   memset (hw_addr, 0, sizeof (hw_addr));
15559
15560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15561     {
15562       if (unformat (i, "name %s", &host_if_name))
15563         vec_add1 (host_if_name, 0);
15564       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15565         random_hw_addr = 0;
15566       else
15567         break;
15568     }
15569
15570   if (!vec_len (host_if_name))
15571     {
15572       errmsg ("host-interface name must be specified");
15573       return -99;
15574     }
15575
15576   if (vec_len (host_if_name) > 64)
15577     {
15578       errmsg ("host-interface name too long");
15579       return -99;
15580     }
15581
15582   M (AF_PACKET_CREATE, mp);
15583
15584   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15585   clib_memcpy (mp->hw_addr, hw_addr, 6);
15586   mp->use_random_hw_addr = random_hw_addr;
15587   vec_free (host_if_name);
15588
15589   S (mp);
15590   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15591   return ret;
15592 }
15593
15594 static int
15595 api_af_packet_delete (vat_main_t * vam)
15596 {
15597   unformat_input_t *i = vam->input;
15598   vl_api_af_packet_delete_t *mp;
15599   u8 *host_if_name = 0;
15600   int ret;
15601
15602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15603     {
15604       if (unformat (i, "name %s", &host_if_name))
15605         vec_add1 (host_if_name, 0);
15606       else
15607         break;
15608     }
15609
15610   if (!vec_len (host_if_name))
15611     {
15612       errmsg ("host-interface name must be specified");
15613       return -99;
15614     }
15615
15616   if (vec_len (host_if_name) > 64)
15617     {
15618       errmsg ("host-interface name too long");
15619       return -99;
15620     }
15621
15622   M (AF_PACKET_DELETE, mp);
15623
15624   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15625   vec_free (host_if_name);
15626
15627   S (mp);
15628   W (ret);
15629   return ret;
15630 }
15631
15632 static int
15633 api_policer_add_del (vat_main_t * vam)
15634 {
15635   unformat_input_t *i = vam->input;
15636   vl_api_policer_add_del_t *mp;
15637   u8 is_add = 1;
15638   u8 *name = 0;
15639   u32 cir = 0;
15640   u32 eir = 0;
15641   u64 cb = 0;
15642   u64 eb = 0;
15643   u8 rate_type = 0;
15644   u8 round_type = 0;
15645   u8 type = 0;
15646   u8 color_aware = 0;
15647   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15648   int ret;
15649
15650   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15651   conform_action.dscp = 0;
15652   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15653   exceed_action.dscp = 0;
15654   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15655   violate_action.dscp = 0;
15656
15657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15658     {
15659       if (unformat (i, "del"))
15660         is_add = 0;
15661       else if (unformat (i, "name %s", &name))
15662         vec_add1 (name, 0);
15663       else if (unformat (i, "cir %u", &cir))
15664         ;
15665       else if (unformat (i, "eir %u", &eir))
15666         ;
15667       else if (unformat (i, "cb %u", &cb))
15668         ;
15669       else if (unformat (i, "eb %u", &eb))
15670         ;
15671       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15672                          &rate_type))
15673         ;
15674       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15675                          &round_type))
15676         ;
15677       else if (unformat (i, "type %U", unformat_policer_type, &type))
15678         ;
15679       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15680                          &conform_action))
15681         ;
15682       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15683                          &exceed_action))
15684         ;
15685       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15686                          &violate_action))
15687         ;
15688       else if (unformat (i, "color-aware"))
15689         color_aware = 1;
15690       else
15691         break;
15692     }
15693
15694   if (!vec_len (name))
15695     {
15696       errmsg ("policer name must be specified");
15697       return -99;
15698     }
15699
15700   if (vec_len (name) > 64)
15701     {
15702       errmsg ("policer name too long");
15703       return -99;
15704     }
15705
15706   M (POLICER_ADD_DEL, mp);
15707
15708   clib_memcpy (mp->name, name, vec_len (name));
15709   vec_free (name);
15710   mp->is_add = is_add;
15711   mp->cir = cir;
15712   mp->eir = eir;
15713   mp->cb = cb;
15714   mp->eb = eb;
15715   mp->rate_type = rate_type;
15716   mp->round_type = round_type;
15717   mp->type = type;
15718   mp->conform_action_type = conform_action.action_type;
15719   mp->conform_dscp = conform_action.dscp;
15720   mp->exceed_action_type = exceed_action.action_type;
15721   mp->exceed_dscp = exceed_action.dscp;
15722   mp->violate_action_type = violate_action.action_type;
15723   mp->violate_dscp = violate_action.dscp;
15724   mp->color_aware = color_aware;
15725
15726   S (mp);
15727   W (ret);
15728   return ret;
15729 }
15730
15731 static int
15732 api_policer_dump (vat_main_t * vam)
15733 {
15734   unformat_input_t *i = vam->input;
15735   vl_api_policer_dump_t *mp;
15736   vl_api_control_ping_t *mp_ping;
15737   u8 *match_name = 0;
15738   u8 match_name_valid = 0;
15739   int ret;
15740
15741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15742     {
15743       if (unformat (i, "name %s", &match_name))
15744         {
15745           vec_add1 (match_name, 0);
15746           match_name_valid = 1;
15747         }
15748       else
15749         break;
15750     }
15751
15752   M (POLICER_DUMP, mp);
15753   mp->match_name_valid = match_name_valid;
15754   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15755   vec_free (match_name);
15756   /* send it... */
15757   S (mp);
15758
15759   /* Use a control ping for synchronization */
15760   M (CONTROL_PING, mp_ping);
15761   S (mp_ping);
15762
15763   /* Wait for a reply... */
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_policer_classify_set_interface (vat_main_t * vam)
15770 {
15771   unformat_input_t *i = vam->input;
15772   vl_api_policer_classify_set_interface_t *mp;
15773   u32 sw_if_index;
15774   int sw_if_index_set;
15775   u32 ip4_table_index = ~0;
15776   u32 ip6_table_index = ~0;
15777   u32 l2_table_index = ~0;
15778   u8 is_add = 1;
15779   int ret;
15780
15781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15782     {
15783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15784         sw_if_index_set = 1;
15785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15786         sw_if_index_set = 1;
15787       else if (unformat (i, "del"))
15788         is_add = 0;
15789       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15790         ;
15791       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15792         ;
15793       else if (unformat (i, "l2-table %d", &l2_table_index))
15794         ;
15795       else
15796         {
15797           clib_warning ("parse error '%U'", format_unformat_error, i);
15798           return -99;
15799         }
15800     }
15801
15802   if (sw_if_index_set == 0)
15803     {
15804       errmsg ("missing interface name or sw_if_index");
15805       return -99;
15806     }
15807
15808   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15809
15810   mp->sw_if_index = ntohl (sw_if_index);
15811   mp->ip4_table_index = ntohl (ip4_table_index);
15812   mp->ip6_table_index = ntohl (ip6_table_index);
15813   mp->l2_table_index = ntohl (l2_table_index);
15814   mp->is_add = is_add;
15815
15816   S (mp);
15817   W (ret);
15818   return ret;
15819 }
15820
15821 static int
15822 api_policer_classify_dump (vat_main_t * vam)
15823 {
15824   unformat_input_t *i = vam->input;
15825   vl_api_policer_classify_dump_t *mp;
15826   vl_api_control_ping_t *mp_ping;
15827   u8 type = POLICER_CLASSIFY_N_TABLES;
15828   int ret;
15829
15830   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15831     ;
15832   else
15833     {
15834       errmsg ("classify table type must be specified");
15835       return -99;
15836     }
15837
15838   if (!vam->json_output)
15839     {
15840       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15841     }
15842
15843   M (POLICER_CLASSIFY_DUMP, mp);
15844   mp->type = type;
15845   /* send it... */
15846   S (mp);
15847
15848   /* Use a control ping for synchronization */
15849   M (CONTROL_PING, mp_ping);
15850   S (mp_ping);
15851
15852   /* Wait for a reply... */
15853   W (ret);
15854   return ret;
15855 }
15856
15857 static int
15858 api_netmap_create (vat_main_t * vam)
15859 {
15860   unformat_input_t *i = vam->input;
15861   vl_api_netmap_create_t *mp;
15862   u8 *if_name = 0;
15863   u8 hw_addr[6];
15864   u8 random_hw_addr = 1;
15865   u8 is_pipe = 0;
15866   u8 is_master = 0;
15867   int ret;
15868
15869   memset (hw_addr, 0, sizeof (hw_addr));
15870
15871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15872     {
15873       if (unformat (i, "name %s", &if_name))
15874         vec_add1 (if_name, 0);
15875       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15876         random_hw_addr = 0;
15877       else if (unformat (i, "pipe"))
15878         is_pipe = 1;
15879       else if (unformat (i, "master"))
15880         is_master = 1;
15881       else if (unformat (i, "slave"))
15882         is_master = 0;
15883       else
15884         break;
15885     }
15886
15887   if (!vec_len (if_name))
15888     {
15889       errmsg ("interface name must be specified");
15890       return -99;
15891     }
15892
15893   if (vec_len (if_name) > 64)
15894     {
15895       errmsg ("interface name too long");
15896       return -99;
15897     }
15898
15899   M (NETMAP_CREATE, mp);
15900
15901   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15902   clib_memcpy (mp->hw_addr, hw_addr, 6);
15903   mp->use_random_hw_addr = random_hw_addr;
15904   mp->is_pipe = is_pipe;
15905   mp->is_master = is_master;
15906   vec_free (if_name);
15907
15908   S (mp);
15909   W (ret);
15910   return ret;
15911 }
15912
15913 static int
15914 api_netmap_delete (vat_main_t * vam)
15915 {
15916   unformat_input_t *i = vam->input;
15917   vl_api_netmap_delete_t *mp;
15918   u8 *if_name = 0;
15919   int ret;
15920
15921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15922     {
15923       if (unformat (i, "name %s", &if_name))
15924         vec_add1 (if_name, 0);
15925       else
15926         break;
15927     }
15928
15929   if (!vec_len (if_name))
15930     {
15931       errmsg ("interface name must be specified");
15932       return -99;
15933     }
15934
15935   if (vec_len (if_name) > 64)
15936     {
15937       errmsg ("interface name too long");
15938       return -99;
15939     }
15940
15941   M (NETMAP_DELETE, mp);
15942
15943   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15944   vec_free (if_name);
15945
15946   S (mp);
15947   W (ret);
15948   return ret;
15949 }
15950
15951 static void vl_api_mpls_tunnel_details_t_handler
15952   (vl_api_mpls_tunnel_details_t * mp)
15953 {
15954   vat_main_t *vam = &vat_main;
15955   i32 len = mp->mt_next_hop_n_labels;
15956   i32 i;
15957
15958   print (vam->ofp, "[%d]: via %U %d labels ",
15959          mp->tunnel_index,
15960          format_ip4_address, mp->mt_next_hop,
15961          ntohl (mp->mt_next_hop_sw_if_index));
15962   for (i = 0; i < len; i++)
15963     {
15964       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15965     }
15966   print (vam->ofp, "");
15967 }
15968
15969 static void vl_api_mpls_tunnel_details_t_handler_json
15970   (vl_api_mpls_tunnel_details_t * mp)
15971 {
15972   vat_main_t *vam = &vat_main;
15973   vat_json_node_t *node = NULL;
15974   struct in_addr ip4;
15975   i32 i;
15976   i32 len = mp->mt_next_hop_n_labels;
15977
15978   if (VAT_JSON_ARRAY != vam->json_tree.type)
15979     {
15980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15981       vat_json_init_array (&vam->json_tree);
15982     }
15983   node = vat_json_array_add (&vam->json_tree);
15984
15985   vat_json_init_object (node);
15986   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15987   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15988   vat_json_object_add_ip4 (node, "next_hop", ip4);
15989   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15990                             ntohl (mp->mt_next_hop_sw_if_index));
15991   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15992   vat_json_object_add_uint (node, "label_count", len);
15993   for (i = 0; i < len; i++)
15994     {
15995       vat_json_object_add_uint (node, "label",
15996                                 ntohl (mp->mt_next_hop_out_labels[i]));
15997     }
15998 }
15999
16000 static int
16001 api_mpls_tunnel_dump (vat_main_t * vam)
16002 {
16003   vl_api_mpls_tunnel_dump_t *mp;
16004   vl_api_control_ping_t *mp_ping;
16005   i32 index = -1;
16006   int ret;
16007
16008   /* Parse args required to build the message */
16009   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16010     {
16011       if (!unformat (vam->input, "tunnel_index %d", &index))
16012         {
16013           index = -1;
16014           break;
16015         }
16016     }
16017
16018   print (vam->ofp, "  tunnel_index %d", index);
16019
16020   M (MPLS_TUNNEL_DUMP, mp);
16021   mp->tunnel_index = htonl (index);
16022   S (mp);
16023
16024   /* Use a control ping for synchronization */
16025   M (CONTROL_PING, mp_ping);
16026   S (mp_ping);
16027
16028   W (ret);
16029   return ret;
16030 }
16031
16032 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16033 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16034
16035 static void
16036 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16037 {
16038   vat_main_t *vam = &vat_main;
16039   int count = ntohl (mp->count);
16040   vl_api_fib_path2_t *fp;
16041   int i;
16042
16043   print (vam->ofp,
16044          "table-id %d, label %u, ess_bit %u",
16045          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16046   fp = mp->path;
16047   for (i = 0; i < count; i++)
16048     {
16049       if (fp->afi == IP46_TYPE_IP6)
16050         print (vam->ofp,
16051                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16052                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16053                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16054                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16055                format_ip6_address, fp->next_hop);
16056       else if (fp->afi == IP46_TYPE_IP4)
16057         print (vam->ofp,
16058                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16059                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16060                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16061                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16062                format_ip4_address, fp->next_hop);
16063       fp++;
16064     }
16065 }
16066
16067 static void vl_api_mpls_fib_details_t_handler_json
16068   (vl_api_mpls_fib_details_t * mp)
16069 {
16070   vat_main_t *vam = &vat_main;
16071   int count = ntohl (mp->count);
16072   vat_json_node_t *node = NULL;
16073   struct in_addr ip4;
16074   struct in6_addr ip6;
16075   vl_api_fib_path2_t *fp;
16076   int i;
16077
16078   if (VAT_JSON_ARRAY != vam->json_tree.type)
16079     {
16080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16081       vat_json_init_array (&vam->json_tree);
16082     }
16083   node = vat_json_array_add (&vam->json_tree);
16084
16085   vat_json_init_object (node);
16086   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16087   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16088   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16089   vat_json_object_add_uint (node, "path_count", count);
16090   fp = mp->path;
16091   for (i = 0; i < count; i++)
16092     {
16093       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16094       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16095       vat_json_object_add_uint (node, "is_local", fp->is_local);
16096       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16097       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16098       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16099       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16100       if (fp->afi == IP46_TYPE_IP4)
16101         {
16102           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16103           vat_json_object_add_ip4 (node, "next_hop", ip4);
16104         }
16105       else if (fp->afi == IP46_TYPE_IP6)
16106         {
16107           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16108           vat_json_object_add_ip6 (node, "next_hop", ip6);
16109         }
16110     }
16111 }
16112
16113 static int
16114 api_mpls_fib_dump (vat_main_t * vam)
16115 {
16116   vl_api_mpls_fib_dump_t *mp;
16117   vl_api_control_ping_t *mp_ping;
16118   int ret;
16119
16120   M (MPLS_FIB_DUMP, mp);
16121   S (mp);
16122
16123   /* Use a control ping for synchronization */
16124   M (CONTROL_PING, mp_ping);
16125   S (mp_ping);
16126
16127   W (ret);
16128   return ret;
16129 }
16130
16131 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16132 #define vl_api_ip_fib_details_t_print vl_noop_handler
16133
16134 static void
16135 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16136 {
16137   vat_main_t *vam = &vat_main;
16138   int count = ntohl (mp->count);
16139   vl_api_fib_path_t *fp;
16140   int i;
16141
16142   print (vam->ofp,
16143          "table-id %d, prefix %U/%d",
16144          ntohl (mp->table_id), format_ip4_address, mp->address,
16145          mp->address_length);
16146   fp = mp->path;
16147   for (i = 0; i < count; i++)
16148     {
16149       if (fp->afi == IP46_TYPE_IP6)
16150         print (vam->ofp,
16151                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16152                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16153                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16154                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16155                format_ip6_address, fp->next_hop);
16156       else if (fp->afi == IP46_TYPE_IP4)
16157         print (vam->ofp,
16158                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16159                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16160                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16161                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16162                format_ip4_address, fp->next_hop);
16163       fp++;
16164     }
16165 }
16166
16167 static void vl_api_ip_fib_details_t_handler_json
16168   (vl_api_ip_fib_details_t * mp)
16169 {
16170   vat_main_t *vam = &vat_main;
16171   int count = ntohl (mp->count);
16172   vat_json_node_t *node = NULL;
16173   struct in_addr ip4;
16174   struct in6_addr ip6;
16175   vl_api_fib_path_t *fp;
16176   int i;
16177
16178   if (VAT_JSON_ARRAY != vam->json_tree.type)
16179     {
16180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16181       vat_json_init_array (&vam->json_tree);
16182     }
16183   node = vat_json_array_add (&vam->json_tree);
16184
16185   vat_json_init_object (node);
16186   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16187   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16188   vat_json_object_add_ip4 (node, "prefix", ip4);
16189   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16190   vat_json_object_add_uint (node, "path_count", count);
16191   fp = mp->path;
16192   for (i = 0; i < count; i++)
16193     {
16194       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16195       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16196       vat_json_object_add_uint (node, "is_local", fp->is_local);
16197       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16198       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16199       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16200       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16201       if (fp->afi == IP46_TYPE_IP4)
16202         {
16203           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16204           vat_json_object_add_ip4 (node, "next_hop", ip4);
16205         }
16206       else if (fp->afi == IP46_TYPE_IP6)
16207         {
16208           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16209           vat_json_object_add_ip6 (node, "next_hop", ip6);
16210         }
16211     }
16212 }
16213
16214 static int
16215 api_ip_fib_dump (vat_main_t * vam)
16216 {
16217   vl_api_ip_fib_dump_t *mp;
16218   vl_api_control_ping_t *mp_ping;
16219   int ret;
16220
16221   M (IP_FIB_DUMP, mp);
16222   S (mp);
16223
16224   /* Use a control ping for synchronization */
16225   M (CONTROL_PING, mp_ping);
16226   S (mp_ping);
16227
16228   W (ret);
16229   return ret;
16230 }
16231
16232 static int
16233 api_ip_mfib_dump (vat_main_t * vam)
16234 {
16235   vl_api_ip_mfib_dump_t *mp;
16236   vl_api_control_ping_t *mp_ping;
16237   int ret;
16238
16239   M (IP_MFIB_DUMP, mp);
16240   S (mp);
16241
16242   /* Use a control ping for synchronization */
16243   M (CONTROL_PING, mp_ping);
16244   S (mp_ping);
16245
16246   W (ret);
16247   return ret;
16248 }
16249
16250 static void vl_api_ip_neighbor_details_t_handler
16251   (vl_api_ip_neighbor_details_t * mp)
16252 {
16253   vat_main_t *vam = &vat_main;
16254
16255   print (vam->ofp, "%c %U %U",
16256          (mp->is_static) ? 'S' : 'D',
16257          format_ethernet_address, &mp->mac_address,
16258          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16259          &mp->ip_address);
16260 }
16261
16262 static void vl_api_ip_neighbor_details_t_handler_json
16263   (vl_api_ip_neighbor_details_t * mp)
16264 {
16265
16266   vat_main_t *vam = &vat_main;
16267   vat_json_node_t *node;
16268   struct in_addr ip4;
16269   struct in6_addr ip6;
16270
16271   if (VAT_JSON_ARRAY != vam->json_tree.type)
16272     {
16273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16274       vat_json_init_array (&vam->json_tree);
16275     }
16276   node = vat_json_array_add (&vam->json_tree);
16277
16278   vat_json_init_object (node);
16279   vat_json_object_add_string_copy (node, "flag",
16280                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16281                                    "dynamic");
16282
16283   vat_json_object_add_string_copy (node, "link_layer",
16284                                    format (0, "%U", format_ethernet_address,
16285                                            &mp->mac_address));
16286
16287   if (mp->is_ipv6)
16288     {
16289       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16290       vat_json_object_add_ip6 (node, "ip_address", ip6);
16291     }
16292   else
16293     {
16294       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16295       vat_json_object_add_ip4 (node, "ip_address", ip4);
16296     }
16297 }
16298
16299 static int
16300 api_ip_neighbor_dump (vat_main_t * vam)
16301 {
16302   unformat_input_t *i = vam->input;
16303   vl_api_ip_neighbor_dump_t *mp;
16304   vl_api_control_ping_t *mp_ping;
16305   u8 is_ipv6 = 0;
16306   u32 sw_if_index = ~0;
16307   int ret;
16308
16309   /* Parse args required to build the message */
16310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16311     {
16312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16313         ;
16314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16315         ;
16316       else if (unformat (i, "ip6"))
16317         is_ipv6 = 1;
16318       else
16319         break;
16320     }
16321
16322   if (sw_if_index == ~0)
16323     {
16324       errmsg ("missing interface name or sw_if_index");
16325       return -99;
16326     }
16327
16328   M (IP_NEIGHBOR_DUMP, mp);
16329   mp->is_ipv6 = (u8) is_ipv6;
16330   mp->sw_if_index = ntohl (sw_if_index);
16331   S (mp);
16332
16333   /* Use a control ping for synchronization */
16334   M (CONTROL_PING, mp_ping);
16335   S (mp_ping);
16336
16337   W (ret);
16338   return ret;
16339 }
16340
16341 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16342 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16343
16344 static void
16345 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16346 {
16347   vat_main_t *vam = &vat_main;
16348   int count = ntohl (mp->count);
16349   vl_api_fib_path_t *fp;
16350   int i;
16351
16352   print (vam->ofp,
16353          "table-id %d, prefix %U/%d",
16354          ntohl (mp->table_id), format_ip6_address, mp->address,
16355          mp->address_length);
16356   fp = mp->path;
16357   for (i = 0; i < count; i++)
16358     {
16359       if (fp->afi == IP46_TYPE_IP6)
16360         print (vam->ofp,
16361                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16362                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16363                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16364                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16365                format_ip6_address, fp->next_hop);
16366       else if (fp->afi == IP46_TYPE_IP4)
16367         print (vam->ofp,
16368                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16369                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16370                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16371                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16372                format_ip4_address, fp->next_hop);
16373       fp++;
16374     }
16375 }
16376
16377 static void vl_api_ip6_fib_details_t_handler_json
16378   (vl_api_ip6_fib_details_t * mp)
16379 {
16380   vat_main_t *vam = &vat_main;
16381   int count = ntohl (mp->count);
16382   vat_json_node_t *node = NULL;
16383   struct in_addr ip4;
16384   struct in6_addr ip6;
16385   vl_api_fib_path_t *fp;
16386   int i;
16387
16388   if (VAT_JSON_ARRAY != vam->json_tree.type)
16389     {
16390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16391       vat_json_init_array (&vam->json_tree);
16392     }
16393   node = vat_json_array_add (&vam->json_tree);
16394
16395   vat_json_init_object (node);
16396   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16397   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16398   vat_json_object_add_ip6 (node, "prefix", ip6);
16399   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16400   vat_json_object_add_uint (node, "path_count", count);
16401   fp = mp->path;
16402   for (i = 0; i < count; i++)
16403     {
16404       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16405       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16406       vat_json_object_add_uint (node, "is_local", fp->is_local);
16407       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16408       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16409       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16410       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16411       if (fp->afi == IP46_TYPE_IP4)
16412         {
16413           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16414           vat_json_object_add_ip4 (node, "next_hop", ip4);
16415         }
16416       else if (fp->afi == IP46_TYPE_IP6)
16417         {
16418           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16419           vat_json_object_add_ip6 (node, "next_hop", ip6);
16420         }
16421     }
16422 }
16423
16424 static int
16425 api_ip6_fib_dump (vat_main_t * vam)
16426 {
16427   vl_api_ip6_fib_dump_t *mp;
16428   vl_api_control_ping_t *mp_ping;
16429   int ret;
16430
16431   M (IP6_FIB_DUMP, mp);
16432   S (mp);
16433
16434   /* Use a control ping for synchronization */
16435   M (CONTROL_PING, mp_ping);
16436   S (mp_ping);
16437
16438   W (ret);
16439   return ret;
16440 }
16441
16442 static int
16443 api_ip6_mfib_dump (vat_main_t * vam)
16444 {
16445   vl_api_ip6_mfib_dump_t *mp;
16446   vl_api_control_ping_t *mp_ping;
16447   int ret;
16448
16449   M (IP6_MFIB_DUMP, mp);
16450   S (mp);
16451
16452   /* Use a control ping for synchronization */
16453   M (CONTROL_PING, mp_ping);
16454   S (mp_ping);
16455
16456   W (ret);
16457   return ret;
16458 }
16459
16460 int
16461 api_classify_table_ids (vat_main_t * vam)
16462 {
16463   vl_api_classify_table_ids_t *mp;
16464   int ret;
16465
16466   /* Construct the API message */
16467   M (CLASSIFY_TABLE_IDS, mp);
16468   mp->context = 0;
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473 }
16474
16475 int
16476 api_classify_table_by_interface (vat_main_t * vam)
16477 {
16478   unformat_input_t *input = vam->input;
16479   vl_api_classify_table_by_interface_t *mp;
16480
16481   u32 sw_if_index = ~0;
16482   int ret;
16483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16484     {
16485       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16486         ;
16487       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16488         ;
16489       else
16490         break;
16491     }
16492   if (sw_if_index == ~0)
16493     {
16494       errmsg ("missing interface name or sw_if_index");
16495       return -99;
16496     }
16497
16498   /* Construct the API message */
16499   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16500   mp->context = 0;
16501   mp->sw_if_index = ntohl (sw_if_index);
16502
16503   S (mp);
16504   W (ret);
16505   return ret;
16506 }
16507
16508 int
16509 api_classify_table_info (vat_main_t * vam)
16510 {
16511   unformat_input_t *input = vam->input;
16512   vl_api_classify_table_info_t *mp;
16513
16514   u32 table_id = ~0;
16515   int ret;
16516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16517     {
16518       if (unformat (input, "table_id %d", &table_id))
16519         ;
16520       else
16521         break;
16522     }
16523   if (table_id == ~0)
16524     {
16525       errmsg ("missing table id");
16526       return -99;
16527     }
16528
16529   /* Construct the API message */
16530   M (CLASSIFY_TABLE_INFO, mp);
16531   mp->context = 0;
16532   mp->table_id = ntohl (table_id);
16533
16534   S (mp);
16535   W (ret);
16536   return ret;
16537 }
16538
16539 int
16540 api_classify_session_dump (vat_main_t * vam)
16541 {
16542   unformat_input_t *input = vam->input;
16543   vl_api_classify_session_dump_t *mp;
16544   vl_api_control_ping_t *mp_ping;
16545
16546   u32 table_id = ~0;
16547   int ret;
16548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16549     {
16550       if (unformat (input, "table_id %d", &table_id))
16551         ;
16552       else
16553         break;
16554     }
16555   if (table_id == ~0)
16556     {
16557       errmsg ("missing table id");
16558       return -99;
16559     }
16560
16561   /* Construct the API message */
16562   M (CLASSIFY_SESSION_DUMP, mp);
16563   mp->context = 0;
16564   mp->table_id = ntohl (table_id);
16565   S (mp);
16566
16567   /* Use a control ping for synchronization */
16568   M (CONTROL_PING, mp_ping);
16569   S (mp_ping);
16570
16571   W (ret);
16572   return ret;
16573 }
16574
16575 static void
16576 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16577 {
16578   vat_main_t *vam = &vat_main;
16579
16580   print (vam->ofp, "collector_address %U, collector_port %d, "
16581          "src_address %U, vrf_id %d, path_mtu %u, "
16582          "template_interval %u, udp_checksum %d",
16583          format_ip4_address, mp->collector_address,
16584          ntohs (mp->collector_port),
16585          format_ip4_address, mp->src_address,
16586          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16587          ntohl (mp->template_interval), mp->udp_checksum);
16588
16589   vam->retval = 0;
16590   vam->result_ready = 1;
16591 }
16592
16593 static void
16594   vl_api_ipfix_exporter_details_t_handler_json
16595   (vl_api_ipfix_exporter_details_t * mp)
16596 {
16597   vat_main_t *vam = &vat_main;
16598   vat_json_node_t node;
16599   struct in_addr collector_address;
16600   struct in_addr src_address;
16601
16602   vat_json_init_object (&node);
16603   clib_memcpy (&collector_address, &mp->collector_address,
16604                sizeof (collector_address));
16605   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16606   vat_json_object_add_uint (&node, "collector_port",
16607                             ntohs (mp->collector_port));
16608   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16609   vat_json_object_add_ip4 (&node, "src_address", src_address);
16610   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16611   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16612   vat_json_object_add_uint (&node, "template_interval",
16613                             ntohl (mp->template_interval));
16614   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16615
16616   vat_json_print (vam->ofp, &node);
16617   vat_json_free (&node);
16618   vam->retval = 0;
16619   vam->result_ready = 1;
16620 }
16621
16622 int
16623 api_ipfix_exporter_dump (vat_main_t * vam)
16624 {
16625   vl_api_ipfix_exporter_dump_t *mp;
16626   int ret;
16627
16628   /* Construct the API message */
16629   M (IPFIX_EXPORTER_DUMP, mp);
16630   mp->context = 0;
16631
16632   S (mp);
16633   W (ret);
16634   return ret;
16635 }
16636
16637 static int
16638 api_ipfix_classify_stream_dump (vat_main_t * vam)
16639 {
16640   vl_api_ipfix_classify_stream_dump_t *mp;
16641   int ret;
16642
16643   /* Construct the API message */
16644   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16645   mp->context = 0;
16646
16647   S (mp);
16648   W (ret);
16649   return ret;
16650   /* NOTREACHED */
16651   return 0;
16652 }
16653
16654 static void
16655   vl_api_ipfix_classify_stream_details_t_handler
16656   (vl_api_ipfix_classify_stream_details_t * mp)
16657 {
16658   vat_main_t *vam = &vat_main;
16659   print (vam->ofp, "domain_id %d, src_port %d",
16660          ntohl (mp->domain_id), ntohs (mp->src_port));
16661   vam->retval = 0;
16662   vam->result_ready = 1;
16663 }
16664
16665 static void
16666   vl_api_ipfix_classify_stream_details_t_handler_json
16667   (vl_api_ipfix_classify_stream_details_t * mp)
16668 {
16669   vat_main_t *vam = &vat_main;
16670   vat_json_node_t node;
16671
16672   vat_json_init_object (&node);
16673   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16674   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16675
16676   vat_json_print (vam->ofp, &node);
16677   vat_json_free (&node);
16678   vam->retval = 0;
16679   vam->result_ready = 1;
16680 }
16681
16682 static int
16683 api_ipfix_classify_table_dump (vat_main_t * vam)
16684 {
16685   vl_api_ipfix_classify_table_dump_t *mp;
16686   vl_api_control_ping_t *mp_ping;
16687   int ret;
16688
16689   if (!vam->json_output)
16690     {
16691       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16692              "transport_protocol");
16693     }
16694
16695   /* Construct the API message */
16696   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16697
16698   /* send it... */
16699   S (mp);
16700
16701   /* Use a control ping for synchronization */
16702   M (CONTROL_PING, mp_ping);
16703   S (mp_ping);
16704
16705   W (ret);
16706   return ret;
16707 }
16708
16709 static void
16710   vl_api_ipfix_classify_table_details_t_handler
16711   (vl_api_ipfix_classify_table_details_t * mp)
16712 {
16713   vat_main_t *vam = &vat_main;
16714   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16715          mp->transport_protocol);
16716 }
16717
16718 static void
16719   vl_api_ipfix_classify_table_details_t_handler_json
16720   (vl_api_ipfix_classify_table_details_t * mp)
16721 {
16722   vat_json_node_t *node = NULL;
16723   vat_main_t *vam = &vat_main;
16724
16725   if (VAT_JSON_ARRAY != vam->json_tree.type)
16726     {
16727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16728       vat_json_init_array (&vam->json_tree);
16729     }
16730
16731   node = vat_json_array_add (&vam->json_tree);
16732   vat_json_init_object (node);
16733
16734   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16735   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16736   vat_json_object_add_uint (node, "transport_protocol",
16737                             mp->transport_protocol);
16738 }
16739
16740 static int
16741 api_sw_interface_span_enable_disable (vat_main_t * vam)
16742 {
16743   unformat_input_t *i = vam->input;
16744   vl_api_sw_interface_span_enable_disable_t *mp;
16745   u32 src_sw_if_index = ~0;
16746   u32 dst_sw_if_index = ~0;
16747   u8 state = 3;
16748   int ret;
16749
16750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16751     {
16752       if (unformat
16753           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16754         ;
16755       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16756         ;
16757       else
16758         if (unformat
16759             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16760         ;
16761       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16762         ;
16763       else if (unformat (i, "disable"))
16764         state = 0;
16765       else if (unformat (i, "rx"))
16766         state = 1;
16767       else if (unformat (i, "tx"))
16768         state = 2;
16769       else if (unformat (i, "both"))
16770         state = 3;
16771       else
16772         break;
16773     }
16774
16775   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16776
16777   mp->sw_if_index_from = htonl (src_sw_if_index);
16778   mp->sw_if_index_to = htonl (dst_sw_if_index);
16779   mp->state = state;
16780
16781   S (mp);
16782   W (ret);
16783   return ret;
16784 }
16785
16786 static void
16787 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16788                                             * mp)
16789 {
16790   vat_main_t *vam = &vat_main;
16791   u8 *sw_if_from_name = 0;
16792   u8 *sw_if_to_name = 0;
16793   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16794   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16795   char *states[] = { "none", "rx", "tx", "both" };
16796   hash_pair_t *p;
16797
16798   /* *INDENT-OFF* */
16799   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16800   ({
16801     if ((u32) p->value[0] == sw_if_index_from)
16802       {
16803         sw_if_from_name = (u8 *)(p->key);
16804         if (sw_if_to_name)
16805           break;
16806       }
16807     if ((u32) p->value[0] == sw_if_index_to)
16808       {
16809         sw_if_to_name = (u8 *)(p->key);
16810         if (sw_if_from_name)
16811           break;
16812       }
16813   }));
16814   /* *INDENT-ON* */
16815   print (vam->ofp, "%20s => %20s (%s)",
16816          sw_if_from_name, sw_if_to_name, states[mp->state]);
16817 }
16818
16819 static void
16820   vl_api_sw_interface_span_details_t_handler_json
16821   (vl_api_sw_interface_span_details_t * mp)
16822 {
16823   vat_main_t *vam = &vat_main;
16824   vat_json_node_t *node = NULL;
16825   u8 *sw_if_from_name = 0;
16826   u8 *sw_if_to_name = 0;
16827   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16828   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16829   hash_pair_t *p;
16830
16831   /* *INDENT-OFF* */
16832   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16833   ({
16834     if ((u32) p->value[0] == sw_if_index_from)
16835       {
16836         sw_if_from_name = (u8 *)(p->key);
16837         if (sw_if_to_name)
16838           break;
16839       }
16840     if ((u32) p->value[0] == sw_if_index_to)
16841       {
16842         sw_if_to_name = (u8 *)(p->key);
16843         if (sw_if_from_name)
16844           break;
16845       }
16846   }));
16847   /* *INDENT-ON* */
16848
16849   if (VAT_JSON_ARRAY != vam->json_tree.type)
16850     {
16851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16852       vat_json_init_array (&vam->json_tree);
16853     }
16854   node = vat_json_array_add (&vam->json_tree);
16855
16856   vat_json_init_object (node);
16857   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16858   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16859   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16860   if (0 != sw_if_to_name)
16861     {
16862       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16863     }
16864   vat_json_object_add_uint (node, "state", mp->state);
16865 }
16866
16867 static int
16868 api_sw_interface_span_dump (vat_main_t * vam)
16869 {
16870   vl_api_sw_interface_span_dump_t *mp;
16871   vl_api_control_ping_t *mp_ping;
16872   int ret;
16873
16874   M (SW_INTERFACE_SPAN_DUMP, mp);
16875   S (mp);
16876
16877   /* Use a control ping for synchronization */
16878   M (CONTROL_PING, mp_ping);
16879   S (mp_ping);
16880
16881   W (ret);
16882   return ret;
16883 }
16884
16885 int
16886 api_pg_create_interface (vat_main_t * vam)
16887 {
16888   unformat_input_t *input = vam->input;
16889   vl_api_pg_create_interface_t *mp;
16890
16891   u32 if_id = ~0;
16892   int ret;
16893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16894     {
16895       if (unformat (input, "if_id %d", &if_id))
16896         ;
16897       else
16898         break;
16899     }
16900   if (if_id == ~0)
16901     {
16902       errmsg ("missing pg interface index");
16903       return -99;
16904     }
16905
16906   /* Construct the API message */
16907   M (PG_CREATE_INTERFACE, mp);
16908   mp->context = 0;
16909   mp->interface_id = ntohl (if_id);
16910
16911   S (mp);
16912   W (ret);
16913   return ret;
16914 }
16915
16916 int
16917 api_pg_capture (vat_main_t * vam)
16918 {
16919   unformat_input_t *input = vam->input;
16920   vl_api_pg_capture_t *mp;
16921
16922   u32 if_id = ~0;
16923   u8 enable = 1;
16924   u32 count = 1;
16925   u8 pcap_file_set = 0;
16926   u8 *pcap_file = 0;
16927   int ret;
16928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16929     {
16930       if (unformat (input, "if_id %d", &if_id))
16931         ;
16932       else if (unformat (input, "pcap %s", &pcap_file))
16933         pcap_file_set = 1;
16934       else if (unformat (input, "count %d", &count))
16935         ;
16936       else if (unformat (input, "disable"))
16937         enable = 0;
16938       else
16939         break;
16940     }
16941   if (if_id == ~0)
16942     {
16943       errmsg ("missing pg interface index");
16944       return -99;
16945     }
16946   if (pcap_file_set > 0)
16947     {
16948       if (vec_len (pcap_file) > 255)
16949         {
16950           errmsg ("pcap file name is too long");
16951           return -99;
16952         }
16953     }
16954
16955   u32 name_len = vec_len (pcap_file);
16956   /* Construct the API message */
16957   M (PG_CAPTURE, mp);
16958   mp->context = 0;
16959   mp->interface_id = ntohl (if_id);
16960   mp->is_enabled = enable;
16961   mp->count = ntohl (count);
16962   mp->pcap_name_length = ntohl (name_len);
16963   if (pcap_file_set != 0)
16964     {
16965       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16966     }
16967   vec_free (pcap_file);
16968
16969   S (mp);
16970   W (ret);
16971   return ret;
16972 }
16973
16974 int
16975 api_pg_enable_disable (vat_main_t * vam)
16976 {
16977   unformat_input_t *input = vam->input;
16978   vl_api_pg_enable_disable_t *mp;
16979
16980   u8 enable = 1;
16981   u8 stream_name_set = 0;
16982   u8 *stream_name = 0;
16983   int ret;
16984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16985     {
16986       if (unformat (input, "stream %s", &stream_name))
16987         stream_name_set = 1;
16988       else if (unformat (input, "disable"))
16989         enable = 0;
16990       else
16991         break;
16992     }
16993
16994   if (stream_name_set > 0)
16995     {
16996       if (vec_len (stream_name) > 255)
16997         {
16998           errmsg ("stream name too long");
16999           return -99;
17000         }
17001     }
17002
17003   u32 name_len = vec_len (stream_name);
17004   /* Construct the API message */
17005   M (PG_ENABLE_DISABLE, mp);
17006   mp->context = 0;
17007   mp->is_enabled = enable;
17008   if (stream_name_set != 0)
17009     {
17010       mp->stream_name_length = ntohl (name_len);
17011       clib_memcpy (mp->stream_name, stream_name, name_len);
17012     }
17013   vec_free (stream_name);
17014
17015   S (mp);
17016   W (ret);
17017   return ret;
17018 }
17019
17020 int
17021 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17022 {
17023   unformat_input_t *input = vam->input;
17024   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17025
17026   u16 *low_ports = 0;
17027   u16 *high_ports = 0;
17028   u16 this_low;
17029   u16 this_hi;
17030   ip4_address_t ip4_addr;
17031   ip6_address_t ip6_addr;
17032   u32 length;
17033   u32 tmp, tmp2;
17034   u8 prefix_set = 0;
17035   u32 vrf_id = ~0;
17036   u8 is_add = 1;
17037   u8 is_ipv6 = 0;
17038   int ret;
17039
17040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17041     {
17042       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17043         {
17044           prefix_set = 1;
17045         }
17046       else
17047         if (unformat
17048             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17049         {
17050           prefix_set = 1;
17051           is_ipv6 = 1;
17052         }
17053       else if (unformat (input, "vrf %d", &vrf_id))
17054         ;
17055       else if (unformat (input, "del"))
17056         is_add = 0;
17057       else if (unformat (input, "port %d", &tmp))
17058         {
17059           if (tmp == 0 || tmp > 65535)
17060             {
17061               errmsg ("port %d out of range", tmp);
17062               return -99;
17063             }
17064           this_low = tmp;
17065           this_hi = this_low + 1;
17066           vec_add1 (low_ports, this_low);
17067           vec_add1 (high_ports, this_hi);
17068         }
17069       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17070         {
17071           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17072             {
17073               errmsg ("incorrect range parameters");
17074               return -99;
17075             }
17076           this_low = tmp;
17077           /* Note: in debug CLI +1 is added to high before
17078              passing to real fn that does "the work"
17079              (ip_source_and_port_range_check_add_del).
17080              This fn is a wrapper around the binary API fn a
17081              control plane will call, which expects this increment
17082              to have occurred. Hence letting the binary API control
17083              plane fn do the increment for consistency between VAT
17084              and other control planes.
17085            */
17086           this_hi = tmp2;
17087           vec_add1 (low_ports, this_low);
17088           vec_add1 (high_ports, this_hi);
17089         }
17090       else
17091         break;
17092     }
17093
17094   if (prefix_set == 0)
17095     {
17096       errmsg ("<address>/<mask> not specified");
17097       return -99;
17098     }
17099
17100   if (vrf_id == ~0)
17101     {
17102       errmsg ("VRF ID required, not specified");
17103       return -99;
17104     }
17105
17106   if (vrf_id == 0)
17107     {
17108       errmsg
17109         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17110       return -99;
17111     }
17112
17113   if (vec_len (low_ports) == 0)
17114     {
17115       errmsg ("At least one port or port range required");
17116       return -99;
17117     }
17118
17119   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17120
17121   mp->is_add = is_add;
17122
17123   if (is_ipv6)
17124     {
17125       mp->is_ipv6 = 1;
17126       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17127     }
17128   else
17129     {
17130       mp->is_ipv6 = 0;
17131       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17132     }
17133
17134   mp->mask_length = length;
17135   mp->number_of_ranges = vec_len (low_ports);
17136
17137   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17138   vec_free (low_ports);
17139
17140   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17141   vec_free (high_ports);
17142
17143   mp->vrf_id = ntohl (vrf_id);
17144
17145   S (mp);
17146   W (ret);
17147   return ret;
17148 }
17149
17150 int
17151 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17152 {
17153   unformat_input_t *input = vam->input;
17154   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17155   u32 sw_if_index = ~0;
17156   int vrf_set = 0;
17157   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17158   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17159   u8 is_add = 1;
17160   int ret;
17161
17162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17163     {
17164       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17165         ;
17166       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17167         ;
17168       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17169         vrf_set = 1;
17170       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17171         vrf_set = 1;
17172       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17173         vrf_set = 1;
17174       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17175         vrf_set = 1;
17176       else if (unformat (input, "del"))
17177         is_add = 0;
17178       else
17179         break;
17180     }
17181
17182   if (sw_if_index == ~0)
17183     {
17184       errmsg ("Interface required but not specified");
17185       return -99;
17186     }
17187
17188   if (vrf_set == 0)
17189     {
17190       errmsg ("VRF ID required but not specified");
17191       return -99;
17192     }
17193
17194   if (tcp_out_vrf_id == 0
17195       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17196     {
17197       errmsg
17198         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17199       return -99;
17200     }
17201
17202   /* Construct the API message */
17203   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17204
17205   mp->sw_if_index = ntohl (sw_if_index);
17206   mp->is_add = is_add;
17207   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17208   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17209   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17210   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17211
17212   /* send it... */
17213   S (mp);
17214
17215   /* Wait for a reply... */
17216   W (ret);
17217   return ret;
17218 }
17219
17220 static int
17221 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17222 {
17223   unformat_input_t *i = vam->input;
17224   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17225   u32 local_sa_id = 0;
17226   u32 remote_sa_id = 0;
17227   ip4_address_t src_address;
17228   ip4_address_t dst_address;
17229   u8 is_add = 1;
17230   int ret;
17231
17232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17233     {
17234       if (unformat (i, "local_sa %d", &local_sa_id))
17235         ;
17236       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17237         ;
17238       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17239         ;
17240       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17241         ;
17242       else if (unformat (i, "del"))
17243         is_add = 0;
17244       else
17245         {
17246           clib_warning ("parse error '%U'", format_unformat_error, i);
17247           return -99;
17248         }
17249     }
17250
17251   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17252
17253   mp->local_sa_id = ntohl (local_sa_id);
17254   mp->remote_sa_id = ntohl (remote_sa_id);
17255   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17256   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17257   mp->is_add = is_add;
17258
17259   S (mp);
17260   W (ret);
17261   return ret;
17262 }
17263
17264 static int
17265 api_punt (vat_main_t * vam)
17266 {
17267   unformat_input_t *i = vam->input;
17268   vl_api_punt_t *mp;
17269   u32 ipv = ~0;
17270   u32 protocol = ~0;
17271   u32 port = ~0;
17272   int is_add = 1;
17273   int ret;
17274
17275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17276     {
17277       if (unformat (i, "ip %d", &ipv))
17278         ;
17279       else if (unformat (i, "protocol %d", &protocol))
17280         ;
17281       else if (unformat (i, "port %d", &port))
17282         ;
17283       else if (unformat (i, "del"))
17284         is_add = 0;
17285       else
17286         {
17287           clib_warning ("parse error '%U'", format_unformat_error, i);
17288           return -99;
17289         }
17290     }
17291
17292   M (PUNT, mp);
17293
17294   mp->is_add = (u8) is_add;
17295   mp->ipv = (u8) ipv;
17296   mp->l4_protocol = (u8) protocol;
17297   mp->l4_port = htons ((u16) port);
17298
17299   S (mp);
17300   W (ret);
17301   return ret;
17302 }
17303
17304 static void vl_api_ipsec_gre_tunnel_details_t_handler
17305   (vl_api_ipsec_gre_tunnel_details_t * mp)
17306 {
17307   vat_main_t *vam = &vat_main;
17308
17309   print (vam->ofp, "%11d%15U%15U%14d%14d",
17310          ntohl (mp->sw_if_index),
17311          format_ip4_address, &mp->src_address,
17312          format_ip4_address, &mp->dst_address,
17313          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17314 }
17315
17316 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17317   (vl_api_ipsec_gre_tunnel_details_t * mp)
17318 {
17319   vat_main_t *vam = &vat_main;
17320   vat_json_node_t *node = NULL;
17321   struct in_addr ip4;
17322
17323   if (VAT_JSON_ARRAY != vam->json_tree.type)
17324     {
17325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17326       vat_json_init_array (&vam->json_tree);
17327     }
17328   node = vat_json_array_add (&vam->json_tree);
17329
17330   vat_json_init_object (node);
17331   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17332   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17333   vat_json_object_add_ip4 (node, "src_address", ip4);
17334   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17335   vat_json_object_add_ip4 (node, "dst_address", ip4);
17336   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17337   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17338 }
17339
17340 static int
17341 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17342 {
17343   unformat_input_t *i = vam->input;
17344   vl_api_ipsec_gre_tunnel_dump_t *mp;
17345   vl_api_control_ping_t *mp_ping;
17346   u32 sw_if_index;
17347   u8 sw_if_index_set = 0;
17348   int ret;
17349
17350   /* Parse args required to build the message */
17351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17352     {
17353       if (unformat (i, "sw_if_index %d", &sw_if_index))
17354         sw_if_index_set = 1;
17355       else
17356         break;
17357     }
17358
17359   if (sw_if_index_set == 0)
17360     {
17361       sw_if_index = ~0;
17362     }
17363
17364   if (!vam->json_output)
17365     {
17366       print (vam->ofp, "%11s%15s%15s%14s%14s",
17367              "sw_if_index", "src_address", "dst_address",
17368              "local_sa_id", "remote_sa_id");
17369     }
17370
17371   /* Get list of gre-tunnel interfaces */
17372   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17373
17374   mp->sw_if_index = htonl (sw_if_index);
17375
17376   S (mp);
17377
17378   /* Use a control ping for synchronization */
17379   M (CONTROL_PING, mp_ping);
17380   S (mp_ping);
17381
17382   W (ret);
17383   return ret;
17384 }
17385
17386 static int
17387 api_delete_subif (vat_main_t * vam)
17388 {
17389   unformat_input_t *i = vam->input;
17390   vl_api_delete_subif_t *mp;
17391   u32 sw_if_index = ~0;
17392   int ret;
17393
17394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17395     {
17396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17397         ;
17398       if (unformat (i, "sw_if_index %d", &sw_if_index))
17399         ;
17400       else
17401         break;
17402     }
17403
17404   if (sw_if_index == ~0)
17405     {
17406       errmsg ("missing sw_if_index");
17407       return -99;
17408     }
17409
17410   /* Construct the API message */
17411   M (DELETE_SUBIF, mp);
17412   mp->sw_if_index = ntohl (sw_if_index);
17413
17414   S (mp);
17415   W (ret);
17416   return ret;
17417 }
17418
17419 #define foreach_pbb_vtr_op      \
17420 _("disable",  L2_VTR_DISABLED)  \
17421 _("pop",  L2_VTR_POP_2)         \
17422 _("push",  L2_VTR_PUSH_2)
17423
17424 static int
17425 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17426 {
17427   unformat_input_t *i = vam->input;
17428   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17429   u32 sw_if_index = ~0, vtr_op = ~0;
17430   u16 outer_tag = ~0;
17431   u8 dmac[6], smac[6];
17432   u8 dmac_set = 0, smac_set = 0;
17433   u16 vlanid = 0;
17434   u32 sid = ~0;
17435   u32 tmp;
17436   int ret;
17437
17438   /* Shut up coverity */
17439   memset (dmac, 0, sizeof (dmac));
17440   memset (smac, 0, sizeof (smac));
17441
17442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17443     {
17444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17445         ;
17446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17447         ;
17448       else if (unformat (i, "vtr_op %d", &vtr_op))
17449         ;
17450 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17451       foreach_pbb_vtr_op
17452 #undef _
17453         else if (unformat (i, "translate_pbb_stag"))
17454         {
17455           if (unformat (i, "%d", &tmp))
17456             {
17457               vtr_op = L2_VTR_TRANSLATE_2_1;
17458               outer_tag = tmp;
17459             }
17460           else
17461             {
17462               errmsg
17463                 ("translate_pbb_stag operation requires outer tag definition");
17464               return -99;
17465             }
17466         }
17467       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17468         dmac_set++;
17469       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17470         smac_set++;
17471       else if (unformat (i, "sid %d", &sid))
17472         ;
17473       else if (unformat (i, "vlanid %d", &tmp))
17474         vlanid = tmp;
17475       else
17476         {
17477           clib_warning ("parse error '%U'", format_unformat_error, i);
17478           return -99;
17479         }
17480     }
17481
17482   if ((sw_if_index == ~0) || (vtr_op == ~0))
17483     {
17484       errmsg ("missing sw_if_index or vtr operation");
17485       return -99;
17486     }
17487   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17488       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17489     {
17490       errmsg
17491         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17492       return -99;
17493     }
17494
17495   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17496   mp->sw_if_index = ntohl (sw_if_index);
17497   mp->vtr_op = ntohl (vtr_op);
17498   mp->outer_tag = ntohs (outer_tag);
17499   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17500   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17501   mp->b_vlanid = ntohs (vlanid);
17502   mp->i_sid = ntohl (sid);
17503
17504   S (mp);
17505   W (ret);
17506   return ret;
17507 }
17508
17509 static int
17510 api_flow_classify_set_interface (vat_main_t * vam)
17511 {
17512   unformat_input_t *i = vam->input;
17513   vl_api_flow_classify_set_interface_t *mp;
17514   u32 sw_if_index;
17515   int sw_if_index_set;
17516   u32 ip4_table_index = ~0;
17517   u32 ip6_table_index = ~0;
17518   u8 is_add = 1;
17519   int ret;
17520
17521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17522     {
17523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17524         sw_if_index_set = 1;
17525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17526         sw_if_index_set = 1;
17527       else if (unformat (i, "del"))
17528         is_add = 0;
17529       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17530         ;
17531       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17532         ;
17533       else
17534         {
17535           clib_warning ("parse error '%U'", format_unformat_error, i);
17536           return -99;
17537         }
17538     }
17539
17540   if (sw_if_index_set == 0)
17541     {
17542       errmsg ("missing interface name or sw_if_index");
17543       return -99;
17544     }
17545
17546   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17547
17548   mp->sw_if_index = ntohl (sw_if_index);
17549   mp->ip4_table_index = ntohl (ip4_table_index);
17550   mp->ip6_table_index = ntohl (ip6_table_index);
17551   mp->is_add = is_add;
17552
17553   S (mp);
17554   W (ret);
17555   return ret;
17556 }
17557
17558 static int
17559 api_flow_classify_dump (vat_main_t * vam)
17560 {
17561   unformat_input_t *i = vam->input;
17562   vl_api_flow_classify_dump_t *mp;
17563   vl_api_control_ping_t *mp_ping;
17564   u8 type = FLOW_CLASSIFY_N_TABLES;
17565   int ret;
17566
17567   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17568     ;
17569   else
17570     {
17571       errmsg ("classify table type must be specified");
17572       return -99;
17573     }
17574
17575   if (!vam->json_output)
17576     {
17577       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17578     }
17579
17580   M (FLOW_CLASSIFY_DUMP, mp);
17581   mp->type = type;
17582   /* send it... */
17583   S (mp);
17584
17585   /* Use a control ping for synchronization */
17586   M (CONTROL_PING, mp_ping);
17587   S (mp_ping);
17588
17589   /* Wait for a reply... */
17590   W (ret);
17591   return ret;
17592 }
17593
17594 static int
17595 api_feature_enable_disable (vat_main_t * vam)
17596 {
17597   unformat_input_t *i = vam->input;
17598   vl_api_feature_enable_disable_t *mp;
17599   u8 *arc_name = 0;
17600   u8 *feature_name = 0;
17601   u32 sw_if_index = ~0;
17602   u8 enable = 1;
17603   int ret;
17604
17605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17606     {
17607       if (unformat (i, "arc_name %s", &arc_name))
17608         ;
17609       else if (unformat (i, "feature_name %s", &feature_name))
17610         ;
17611       else
17612         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17613         ;
17614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17615         ;
17616       else if (unformat (i, "disable"))
17617         enable = 0;
17618       else
17619         break;
17620     }
17621
17622   if (arc_name == 0)
17623     {
17624       errmsg ("missing arc name");
17625       return -99;
17626     }
17627   if (vec_len (arc_name) > 63)
17628     {
17629       errmsg ("arc name too long");
17630     }
17631
17632   if (feature_name == 0)
17633     {
17634       errmsg ("missing feature name");
17635       return -99;
17636     }
17637   if (vec_len (feature_name) > 63)
17638     {
17639       errmsg ("feature name too long");
17640     }
17641
17642   if (sw_if_index == ~0)
17643     {
17644       errmsg ("missing interface name or sw_if_index");
17645       return -99;
17646     }
17647
17648   /* Construct the API message */
17649   M (FEATURE_ENABLE_DISABLE, mp);
17650   mp->sw_if_index = ntohl (sw_if_index);
17651   mp->enable = enable;
17652   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17653   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17654   vec_free (arc_name);
17655   vec_free (feature_name);
17656
17657   S (mp);
17658   W (ret);
17659   return ret;
17660 }
17661
17662 static int
17663 api_sw_interface_tag_add_del (vat_main_t * vam)
17664 {
17665   unformat_input_t *i = vam->input;
17666   vl_api_sw_interface_tag_add_del_t *mp;
17667   u32 sw_if_index = ~0;
17668   u8 *tag = 0;
17669   u8 enable = 1;
17670   int ret;
17671
17672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17673     {
17674       if (unformat (i, "tag %s", &tag))
17675         ;
17676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17677         ;
17678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17679         ;
17680       else if (unformat (i, "del"))
17681         enable = 0;
17682       else
17683         break;
17684     }
17685
17686   if (sw_if_index == ~0)
17687     {
17688       errmsg ("missing interface name or sw_if_index");
17689       return -99;
17690     }
17691
17692   if (enable && (tag == 0))
17693     {
17694       errmsg ("no tag specified");
17695       return -99;
17696     }
17697
17698   /* Construct the API message */
17699   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17700   mp->sw_if_index = ntohl (sw_if_index);
17701   mp->is_add = enable;
17702   if (enable)
17703     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17704   vec_free (tag);
17705
17706   S (mp);
17707   W (ret);
17708   return ret;
17709 }
17710
17711 static void vl_api_l2_xconnect_details_t_handler
17712   (vl_api_l2_xconnect_details_t * mp)
17713 {
17714   vat_main_t *vam = &vat_main;
17715
17716   print (vam->ofp, "%15d%15d",
17717          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17718 }
17719
17720 static void vl_api_l2_xconnect_details_t_handler_json
17721   (vl_api_l2_xconnect_details_t * mp)
17722 {
17723   vat_main_t *vam = &vat_main;
17724   vat_json_node_t *node = NULL;
17725
17726   if (VAT_JSON_ARRAY != vam->json_tree.type)
17727     {
17728       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17729       vat_json_init_array (&vam->json_tree);
17730     }
17731   node = vat_json_array_add (&vam->json_tree);
17732
17733   vat_json_init_object (node);
17734   vat_json_object_add_uint (node, "rx_sw_if_index",
17735                             ntohl (mp->rx_sw_if_index));
17736   vat_json_object_add_uint (node, "tx_sw_if_index",
17737                             ntohl (mp->tx_sw_if_index));
17738 }
17739
17740 static int
17741 api_l2_xconnect_dump (vat_main_t * vam)
17742 {
17743   vl_api_l2_xconnect_dump_t *mp;
17744   vl_api_control_ping_t *mp_ping;
17745   int ret;
17746
17747   if (!vam->json_output)
17748     {
17749       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17750     }
17751
17752   M (L2_XCONNECT_DUMP, mp);
17753
17754   S (mp);
17755
17756   /* Use a control ping for synchronization */
17757   M (CONTROL_PING, mp_ping);
17758   S (mp_ping);
17759
17760   W (ret);
17761   return ret;
17762 }
17763
17764 static int
17765 api_sw_interface_set_mtu (vat_main_t * vam)
17766 {
17767   unformat_input_t *i = vam->input;
17768   vl_api_sw_interface_set_mtu_t *mp;
17769   u32 sw_if_index = ~0;
17770   u32 mtu = 0;
17771   int ret;
17772
17773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17774     {
17775       if (unformat (i, "mtu %d", &mtu))
17776         ;
17777       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17778         ;
17779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17780         ;
17781       else
17782         break;
17783     }
17784
17785   if (sw_if_index == ~0)
17786     {
17787       errmsg ("missing interface name or sw_if_index");
17788       return -99;
17789     }
17790
17791   if (mtu == 0)
17792     {
17793       errmsg ("no mtu specified");
17794       return -99;
17795     }
17796
17797   /* Construct the API message */
17798   M (SW_INTERFACE_SET_MTU, mp);
17799   mp->sw_if_index = ntohl (sw_if_index);
17800   mp->mtu = ntohs ((u16) mtu);
17801
17802   S (mp);
17803   W (ret);
17804   return ret;
17805 }
17806
17807
17808 static int
17809 q_or_quit (vat_main_t * vam)
17810 {
17811 #if VPP_API_TEST_BUILTIN == 0
17812   longjmp (vam->jump_buf, 1);
17813 #endif
17814   return 0;                     /* not so much */
17815 }
17816
17817 static int
17818 q (vat_main_t * vam)
17819 {
17820   return q_or_quit (vam);
17821 }
17822
17823 static int
17824 quit (vat_main_t * vam)
17825 {
17826   return q_or_quit (vam);
17827 }
17828
17829 static int
17830 comment (vat_main_t * vam)
17831 {
17832   return 0;
17833 }
17834
17835 static int
17836 cmd_cmp (void *a1, void *a2)
17837 {
17838   u8 **c1 = a1;
17839   u8 **c2 = a2;
17840
17841   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17842 }
17843
17844 static int
17845 help (vat_main_t * vam)
17846 {
17847   u8 **cmds = 0;
17848   u8 *name = 0;
17849   hash_pair_t *p;
17850   unformat_input_t *i = vam->input;
17851   int j;
17852
17853   if (unformat (i, "%s", &name))
17854     {
17855       uword *hs;
17856
17857       vec_add1 (name, 0);
17858
17859       hs = hash_get_mem (vam->help_by_name, name);
17860       if (hs)
17861         print (vam->ofp, "usage: %s %s", name, hs[0]);
17862       else
17863         print (vam->ofp, "No such msg / command '%s'", name);
17864       vec_free (name);
17865       return 0;
17866     }
17867
17868   print (vam->ofp, "Help is available for the following:");
17869
17870     /* *INDENT-OFF* */
17871     hash_foreach_pair (p, vam->function_by_name,
17872     ({
17873       vec_add1 (cmds, (u8 *)(p->key));
17874     }));
17875     /* *INDENT-ON* */
17876
17877   vec_sort_with_function (cmds, cmd_cmp);
17878
17879   for (j = 0; j < vec_len (cmds); j++)
17880     print (vam->ofp, "%s", cmds[j]);
17881
17882   vec_free (cmds);
17883   return 0;
17884 }
17885
17886 static int
17887 set (vat_main_t * vam)
17888 {
17889   u8 *name = 0, *value = 0;
17890   unformat_input_t *i = vam->input;
17891
17892   if (unformat (i, "%s", &name))
17893     {
17894       /* The input buffer is a vector, not a string. */
17895       value = vec_dup (i->buffer);
17896       vec_delete (value, i->index, 0);
17897       /* Almost certainly has a trailing newline */
17898       if (value[vec_len (value) - 1] == '\n')
17899         value[vec_len (value) - 1] = 0;
17900       /* Make sure it's a proper string, one way or the other */
17901       vec_add1 (value, 0);
17902       (void) clib_macro_set_value (&vam->macro_main,
17903                                    (char *) name, (char *) value);
17904     }
17905   else
17906     errmsg ("usage: set <name> <value>");
17907
17908   vec_free (name);
17909   vec_free (value);
17910   return 0;
17911 }
17912
17913 static int
17914 unset (vat_main_t * vam)
17915 {
17916   u8 *name = 0;
17917
17918   if (unformat (vam->input, "%s", &name))
17919     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17920       errmsg ("unset: %s wasn't set", name);
17921   vec_free (name);
17922   return 0;
17923 }
17924
17925 typedef struct
17926 {
17927   u8 *name;
17928   u8 *value;
17929 } macro_sort_t;
17930
17931
17932 static int
17933 macro_sort_cmp (void *a1, void *a2)
17934 {
17935   macro_sort_t *s1 = a1;
17936   macro_sort_t *s2 = a2;
17937
17938   return strcmp ((char *) (s1->name), (char *) (s2->name));
17939 }
17940
17941 static int
17942 dump_macro_table (vat_main_t * vam)
17943 {
17944   macro_sort_t *sort_me = 0, *sm;
17945   int i;
17946   hash_pair_t *p;
17947
17948     /* *INDENT-OFF* */
17949     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17950     ({
17951       vec_add2 (sort_me, sm, 1);
17952       sm->name = (u8 *)(p->key);
17953       sm->value = (u8 *) (p->value[0]);
17954     }));
17955     /* *INDENT-ON* */
17956
17957   vec_sort_with_function (sort_me, macro_sort_cmp);
17958
17959   if (vec_len (sort_me))
17960     print (vam->ofp, "%-15s%s", "Name", "Value");
17961   else
17962     print (vam->ofp, "The macro table is empty...");
17963
17964   for (i = 0; i < vec_len (sort_me); i++)
17965     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17966   return 0;
17967 }
17968
17969 static int
17970 dump_node_table (vat_main_t * vam)
17971 {
17972   int i, j;
17973   vlib_node_t *node, *next_node;
17974
17975   if (vec_len (vam->graph_nodes) == 0)
17976     {
17977       print (vam->ofp, "Node table empty, issue get_node_graph...");
17978       return 0;
17979     }
17980
17981   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17982     {
17983       node = vam->graph_nodes[i];
17984       print (vam->ofp, "[%d] %s", i, node->name);
17985       for (j = 0; j < vec_len (node->next_nodes); j++)
17986         {
17987           if (node->next_nodes[j] != ~0)
17988             {
17989               next_node = vam->graph_nodes[node->next_nodes[j]];
17990               print (vam->ofp, "  [%d] %s", j, next_node->name);
17991             }
17992         }
17993     }
17994   return 0;
17995 }
17996
17997 static int
17998 value_sort_cmp (void *a1, void *a2)
17999 {
18000   name_sort_t *n1 = a1;
18001   name_sort_t *n2 = a2;
18002
18003   if (n1->value < n2->value)
18004     return -1;
18005   if (n1->value > n2->value)
18006     return 1;
18007   return 0;
18008 }
18009
18010
18011 static int
18012 dump_msg_api_table (vat_main_t * vam)
18013 {
18014   api_main_t *am = &api_main;
18015   name_sort_t *nses = 0, *ns;
18016   hash_pair_t *hp;
18017   int i;
18018
18019   /* *INDENT-OFF* */
18020   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18021   ({
18022     vec_add2 (nses, ns, 1);
18023     ns->name = (u8 *)(hp->key);
18024     ns->value = (u32) hp->value[0];
18025   }));
18026   /* *INDENT-ON* */
18027
18028   vec_sort_with_function (nses, value_sort_cmp);
18029
18030   for (i = 0; i < vec_len (nses); i++)
18031     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18032   vec_free (nses);
18033   return 0;
18034 }
18035
18036 static int
18037 get_msg_id (vat_main_t * vam)
18038 {
18039   u8 *name_and_crc;
18040   u32 message_index;
18041
18042   if (unformat (vam->input, "%s", &name_and_crc))
18043     {
18044       message_index = vl_api_get_msg_index (name_and_crc);
18045       if (message_index == ~0)
18046         {
18047           print (vam->ofp, " '%s' not found", name_and_crc);
18048           return 0;
18049         }
18050       print (vam->ofp, " '%s' has message index %d",
18051              name_and_crc, message_index);
18052       return 0;
18053     }
18054   errmsg ("name_and_crc required...");
18055   return 0;
18056 }
18057
18058 static int
18059 search_node_table (vat_main_t * vam)
18060 {
18061   unformat_input_t *line_input = vam->input;
18062   u8 *node_to_find;
18063   int j;
18064   vlib_node_t *node, *next_node;
18065   uword *p;
18066
18067   if (vam->graph_node_index_by_name == 0)
18068     {
18069       print (vam->ofp, "Node table empty, issue get_node_graph...");
18070       return 0;
18071     }
18072
18073   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18074     {
18075       if (unformat (line_input, "%s", &node_to_find))
18076         {
18077           vec_add1 (node_to_find, 0);
18078           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18079           if (p == 0)
18080             {
18081               print (vam->ofp, "%s not found...", node_to_find);
18082               goto out;
18083             }
18084           node = vam->graph_nodes[p[0]];
18085           print (vam->ofp, "[%d] %s", p[0], node->name);
18086           for (j = 0; j < vec_len (node->next_nodes); j++)
18087             {
18088               if (node->next_nodes[j] != ~0)
18089                 {
18090                   next_node = vam->graph_nodes[node->next_nodes[j]];
18091                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18092                 }
18093             }
18094         }
18095
18096       else
18097         {
18098           clib_warning ("parse error '%U'", format_unformat_error,
18099                         line_input);
18100           return -99;
18101         }
18102
18103     out:
18104       vec_free (node_to_find);
18105
18106     }
18107
18108   return 0;
18109 }
18110
18111
18112 static int
18113 script (vat_main_t * vam)
18114 {
18115 #if (VPP_API_TEST_BUILTIN==0)
18116   u8 *s = 0;
18117   char *save_current_file;
18118   unformat_input_t save_input;
18119   jmp_buf save_jump_buf;
18120   u32 save_line_number;
18121
18122   FILE *new_fp, *save_ifp;
18123
18124   if (unformat (vam->input, "%s", &s))
18125     {
18126       new_fp = fopen ((char *) s, "r");
18127       if (new_fp == 0)
18128         {
18129           errmsg ("Couldn't open script file %s", s);
18130           vec_free (s);
18131           return -99;
18132         }
18133     }
18134   else
18135     {
18136       errmsg ("Missing script name");
18137       return -99;
18138     }
18139
18140   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18141   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18142   save_ifp = vam->ifp;
18143   save_line_number = vam->input_line_number;
18144   save_current_file = (char *) vam->current_file;
18145
18146   vam->input_line_number = 0;
18147   vam->ifp = new_fp;
18148   vam->current_file = s;
18149   do_one_file (vam);
18150
18151   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18152   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18153   vam->ifp = save_ifp;
18154   vam->input_line_number = save_line_number;
18155   vam->current_file = (u8 *) save_current_file;
18156   vec_free (s);
18157
18158   return 0;
18159 #else
18160   clib_warning ("use the exec command...");
18161   return -99;
18162 #endif
18163 }
18164
18165 static int
18166 echo (vat_main_t * vam)
18167 {
18168   print (vam->ofp, "%v", vam->input->buffer);
18169   return 0;
18170 }
18171
18172 /* List of API message constructors, CLI names map to api_xxx */
18173 #define foreach_vpe_api_msg                                             \
18174 _(create_loopback,"[mac <mac-addr>]")                                   \
18175 _(sw_interface_dump,"")                                                 \
18176 _(sw_interface_set_flags,                                               \
18177   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18178 _(sw_interface_add_del_address,                                         \
18179   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18180 _(sw_interface_set_table,                                               \
18181   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18182 _(sw_interface_set_mpls_enable,                                         \
18183   "<intfc> | sw_if_index [disable | dis]")                              \
18184 _(sw_interface_set_vpath,                                               \
18185   "<intfc> | sw_if_index <id> enable | disable")                        \
18186 _(sw_interface_set_vxlan_bypass,                                        \
18187   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18188 _(sw_interface_set_l2_xconnect,                                         \
18189   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18190   "enable | disable")                                                   \
18191 _(sw_interface_set_l2_bridge,                                           \
18192   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18193   "[shg <split-horizon-group>] [bvi]\n"                                 \
18194   "enable | disable")                                                   \
18195 _(bridge_domain_add_del,                                                \
18196   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18197 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18198 _(l2fib_add_del,                                                        \
18199   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18200 _(l2_flags,                                                             \
18201   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18202 _(bridge_flags,                                                         \
18203   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18204 _(tap_connect,                                                          \
18205   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18206 _(tap_modify,                                                           \
18207   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18208 _(tap_delete,                                                           \
18209   "<vpp-if-name> | sw_if_index <id>")                                   \
18210 _(sw_interface_tap_dump, "")                                            \
18211 _(ip_add_del_route,                                                     \
18212   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18213   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18214   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18215   "[multipath] [count <n>]")                                            \
18216 _(ip_mroute_add_del,                                                    \
18217   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18218   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18219 _(mpls_route_add_del,                                                   \
18220   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18221   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18222   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18223   "[multipath] [count <n>]")                                            \
18224 _(mpls_ip_bind_unbind,                                                  \
18225   "<label> <addr/len>")                                                 \
18226 _(mpls_tunnel_add_del,                                                  \
18227   " via <addr> [table-id <n>]\n"                                        \
18228   "sw_if_index <id>] [l2]  [del]")                                      \
18229 _(proxy_arp_add_del,                                                    \
18230   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18231 _(proxy_arp_intfc_enable_disable,                                       \
18232   "<intfc> | sw_if_index <id> enable | disable")                        \
18233 _(sw_interface_set_unnumbered,                                          \
18234   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18235 _(ip_neighbor_add_del,                                                  \
18236   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18237   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18238 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18239 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18240 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18241   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18242   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18243   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18244 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18245 _(reset_fib, "vrf <n> [ipv6]")                                          \
18246 _(dhcp_proxy_config,                                                    \
18247   "svr <v46-address> src <v46-address>\n"                               \
18248    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18249 _(dhcp_proxy_set_vss,                                                   \
18250   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18251 _(dhcp_proxy_dump, "ip6")                                               \
18252 _(dhcp_client_config,                                                   \
18253   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18254 _(set_ip_flow_hash,                                                     \
18255   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18256 _(sw_interface_ip6_enable_disable,                                      \
18257   "<intfc> | sw_if_index <id> enable | disable")                        \
18258 _(sw_interface_ip6_set_link_local_address,                              \
18259   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18260 _(sw_interface_ip6nd_ra_prefix,                                         \
18261   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18262   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18263   "[nolink] [isno]")                                                    \
18264 _(sw_interface_ip6nd_ra_config,                                         \
18265   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18266   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18267   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18268 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18269 _(l2_patch_add_del,                                                     \
18270   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18271   "enable | disable")                                                   \
18272 _(sr_tunnel_add_del,                                                    \
18273   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18274   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18275   "[policy <policy_name>]")                                             \
18276 _(sr_policy_add_del,                                                    \
18277   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18278 _(sr_multicast_map_add_del,                                             \
18279   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18280 _(classify_add_del_table,                                               \
18281   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18282   " [del] [del-chain] mask <mask-value>\n"                              \
18283   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18284   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18285 _(classify_add_del_session,                                             \
18286   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18287   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18288   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18289   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18290 _(classify_set_interface_ip_table,                                      \
18291   "<intfc> | sw_if_index <nn> table <nn>")                              \
18292 _(classify_set_interface_l2_tables,                                     \
18293   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18294   "  [other-table <nn>]")                                               \
18295 _(get_node_index, "node <node-name")                                    \
18296 _(add_node_next, "node <node-name> next <next-node-name>")              \
18297 _(l2tpv3_create_tunnel,                                                 \
18298   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18299   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18300   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18301 _(l2tpv3_set_tunnel_cookies,                                            \
18302   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18303   "[new_remote_cookie <nn>]\n")                                         \
18304 _(l2tpv3_interface_enable_disable,                                      \
18305   "<intfc> | sw_if_index <nn> enable | disable")                        \
18306 _(l2tpv3_set_lookup_key,                                                \
18307   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18308 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18309 _(vxlan_add_del_tunnel,                                                 \
18310   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18311   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18312   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18313 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18314 _(gre_add_del_tunnel,                                                   \
18315   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18316 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18317 _(l2_fib_clear_table, "")                                               \
18318 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18319 _(l2_interface_vlan_tag_rewrite,                                        \
18320   "<intfc> | sw_if_index <nn> \n"                                       \
18321   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18322   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18323 _(create_vhost_user_if,                                                 \
18324         "socket <filename> [server] [renumber <dev_instance>] "         \
18325         "[mac <mac_address>]")                                          \
18326 _(modify_vhost_user_if,                                                 \
18327         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18328         "[server] [renumber <dev_instance>]")                           \
18329 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18330 _(sw_interface_vhost_user_dump, "")                                     \
18331 _(show_version, "")                                                     \
18332 _(vxlan_gpe_add_del_tunnel,                                             \
18333   "local <addr> remote <addr> vni <nn>\n"                               \
18334     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18335   "[next-ethernet] [next-nsh]\n")                                       \
18336 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18337 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18338 _(interface_name_renumber,                                              \
18339   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18340 _(input_acl_set_interface,                                              \
18341   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18342   "  [l2-table <nn>] [del]")                                            \
18343 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18344 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18345 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18346 _(ip_dump, "ipv4 | ipv6")                                               \
18347 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18348 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18349   "  spid_id <n> ")                                                     \
18350 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18351   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18352   "  integ_alg <alg> integ_key <hex>")                                  \
18353 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18354   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18355   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18356   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18357 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18358 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18359 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18360   "(auth_data 0x<data> | auth_data <data>)")                            \
18361 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18362   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18363 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18364   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18365   "(local|remote)")                                                     \
18366 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18367 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18368 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18369 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18370 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18371 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18372 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18373 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18374 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18375 _(delete_loopback,"sw_if_index <nn>")                                   \
18376 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18377 _(map_add_domain,                                                       \
18378   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18379   "ip6-src <ip6addr> "                                                  \
18380   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18381 _(map_del_domain, "index <n>")                                          \
18382 _(map_add_del_rule,                                                     \
18383   "index <n> psid <n> dst <ip6addr> [del]")                             \
18384 _(map_domain_dump, "")                                                  \
18385 _(map_rule_dump, "index <map-domain>")                                  \
18386 _(want_interface_events,  "enable|disable")                             \
18387 _(want_stats,"enable|disable")                                          \
18388 _(get_first_msg_id, "client <name>")                                    \
18389 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18390 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18391   "fib-id <nn> [ip4][ip6][default]")                                    \
18392 _(get_node_graph, " ")                                                  \
18393 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18394 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18395 _(ioam_disable, "")                                                     \
18396 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18397                             " sw_if_index <sw_if_index> p <priority> "  \
18398                             "w <weight>] [del]")                        \
18399 _(one_add_del_locator, "locator-set <locator_name> "                    \
18400                         "iface <intf> | sw_if_index <sw_if_index> "     \
18401                         "p <priority> w <weight> [del]")                \
18402 _(one_add_del_local_eid,"vni <vni> eid "                                \
18403                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18404                          "locator-set <locator_name> [del]"             \
18405                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18406 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18407 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18408 _(one_enable_disable, "enable|disable")                                 \
18409 _(one_map_register_enable_disable, "enable|disable")                    \
18410 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18411 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18412                                "[seid <seid>] "                         \
18413                                "rloc <locator> p <prio> "               \
18414                                "w <weight> [rloc <loc> ... ] "          \
18415                                "action <action> [del-all]")             \
18416 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18417                           "<local-eid>")                                \
18418 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18419 _(one_map_request_mode, "src-dst|dst-only")                             \
18420 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18421 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18422 _(one_locator_set_dump, "[local | remote]")                             \
18423 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18424 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18425                        "[local] | [remote]")                            \
18426 _(one_eid_table_vni_dump, "")                                           \
18427 _(one_eid_table_map_dump, "l2|l3")                                      \
18428 _(one_map_resolver_dump, "")                                            \
18429 _(one_map_server_dump, "")                                              \
18430 _(one_adjacencies_get, "vni <vni>")                                     \
18431 _(show_one_rloc_probe_state, "")                                        \
18432 _(show_one_map_register_state, "")                                      \
18433 _(show_one_status, "")                                                  \
18434 _(one_get_map_request_itr_rlocs, "")                                    \
18435 _(show_one_pitr, "")                                                    \
18436 _(show_one_map_request_mode, "")                                        \
18437 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18438                             " sw_if_index <sw_if_index> p <priority> "  \
18439                             "w <weight>] [del]")                        \
18440 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18441                         "iface <intf> | sw_if_index <sw_if_index> "     \
18442                         "p <priority> w <weight> [del]")                \
18443 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18444                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18445                          "locator-set <locator_name> [del]"             \
18446                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18447 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18448 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18449 _(lisp_enable_disable, "enable|disable")                                \
18450 _(lisp_map_register_enable_disable, "enable|disable")                   \
18451 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18452 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18453                                "[seid <seid>] "                         \
18454                                "rloc <locator> p <prio> "               \
18455                                "w <weight> [rloc <loc> ... ] "          \
18456                                "action <action> [del-all]")             \
18457 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18458                           "<local-eid>")                                \
18459 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18460 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18461 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18462 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18463 _(lisp_locator_set_dump, "[local | remote]")                            \
18464 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18465 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18466                        "[local] | [remote]")                            \
18467 _(lisp_eid_table_vni_dump, "")                                          \
18468 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18469 _(lisp_map_resolver_dump, "")                                           \
18470 _(lisp_map_server_dump, "")                                             \
18471 _(lisp_adjacencies_get, "vni <vni>")                                    \
18472 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18473 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18474 _(lisp_gpe_add_del_iface, "up|down")                                    \
18475 _(lisp_gpe_enable_disable, "enable|disable")                            \
18476 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18477   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18478 _(show_lisp_rloc_probe_state, "")                                       \
18479 _(show_lisp_map_register_state, "")                                     \
18480 _(show_lisp_status, "")                                                 \
18481 _(lisp_get_map_request_itr_rlocs, "")                                   \
18482 _(show_lisp_pitr, "")                                                   \
18483 _(show_lisp_map_request_mode, "")                                       \
18484 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18485 _(af_packet_delete, "name <host interface name>")                       \
18486 _(policer_add_del, "name <policer name> <params> [del]")                \
18487 _(policer_dump, "[name <policer name>]")                                \
18488 _(policer_classify_set_interface,                                       \
18489   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18490   "  [l2-table <nn>] [del]")                                            \
18491 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18492 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18493     "[master|slave]")                                                   \
18494 _(netmap_delete, "name <interface name>")                               \
18495 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18496 _(mpls_fib_dump, "")                                                    \
18497 _(classify_table_ids, "")                                               \
18498 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18499 _(classify_table_info, "table_id <nn>")                                 \
18500 _(classify_session_dump, "table_id <nn>")                               \
18501 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18502     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18503     "[template_interval <nn>] [udp_checksum]")                          \
18504 _(ipfix_exporter_dump, "")                                              \
18505 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18506 _(ipfix_classify_stream_dump, "")                                       \
18507 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18508 _(ipfix_classify_table_dump, "")                                        \
18509 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18510 _(sw_interface_span_dump, "")                                           \
18511 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18512 _(pg_create_interface, "if_id <nn>")                                    \
18513 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18514 _(pg_enable_disable, "[stream <id>] disable")                           \
18515 _(ip_source_and_port_range_check_add_del,                               \
18516   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18517 _(ip_source_and_port_range_check_interface_add_del,                     \
18518   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18519   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18520 _(ipsec_gre_add_del_tunnel,                                             \
18521   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18522 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18523 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18524 _(l2_interface_pbb_tag_rewrite,                                         \
18525   "<intfc> | sw_if_index <nn> \n"                                       \
18526   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18527   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18528 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18529 _(flow_classify_set_interface,                                          \
18530   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18531 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18532 _(ip_fib_dump, "")                                                      \
18533 _(ip_mfib_dump, "")                                                     \
18534 _(ip6_fib_dump, "")                                                     \
18535 _(ip6_mfib_dump, "")                                                    \
18536 _(feature_enable_disable, "arc_name <arc_name> "                        \
18537   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18538 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18539 "[disable]")                                                            \
18540 _(l2_xconnect_dump, "")                                                 \
18541 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18542 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18543 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18544
18545 #if DPDK > 0
18546 #define foreach_vpe_dpdk_api_msg                                        \
18547 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18548   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18549   "profile <profile-id>\n")                                             \
18550 _(sw_interface_set_dpdk_hqos_subport,                                   \
18551   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18552   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18553 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18554   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18555 #endif
18556
18557 /* List of command functions, CLI names map directly to functions */
18558 #define foreach_cli_function                                    \
18559 _(comment, "usage: comment <ignore-rest-of-line>")              \
18560 _(dump_interface_table, "usage: dump_interface_table")          \
18561 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18562 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18563 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18564 _(dump_stats_table, "usage: dump_stats_table")                  \
18565 _(dump_macro_table, "usage: dump_macro_table ")                 \
18566 _(dump_node_table, "usage: dump_node_table")                    \
18567 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18568 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18569 _(echo, "usage: echo <message>")                                \
18570 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18571 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18572 _(help, "usage: help")                                          \
18573 _(q, "usage: quit")                                             \
18574 _(quit, "usage: quit")                                          \
18575 _(search_node_table, "usage: search_node_table <name>...")      \
18576 _(set, "usage: set <variable-name> <value>")                    \
18577 _(script, "usage: script <file-name>")                          \
18578 _(unset, "usage: unset <variable-name>")
18579
18580 #define _(N,n)                                  \
18581     static void vl_api_##n##_t_handler_uni      \
18582     (vl_api_##n##_t * mp)                       \
18583     {                                           \
18584         vat_main_t * vam = &vat_main;           \
18585         if (vam->json_output) {                 \
18586             vl_api_##n##_t_handler_json(mp);    \
18587         } else {                                \
18588             vl_api_##n##_t_handler(mp);         \
18589         }                                       \
18590     }
18591 foreach_vpe_api_reply_msg;
18592 #undef _
18593
18594 #if DPDK > 0
18595 #define _(N,n)                                  \
18596     static void vl_api_##n##_t_handler_uni      \
18597     (vl_api_##n##_t * mp)                       \
18598     {                                           \
18599         vat_main_t * vam = &vat_main;           \
18600         if (vam->json_output) {                 \
18601             vl_api_##n##_t_handler_json(mp);    \
18602         } else {                                \
18603             vl_api_##n##_t_handler(mp);         \
18604         }                                       \
18605     }
18606 foreach_vpe_dpdk_api_reply_msg;
18607 #undef _
18608 #endif
18609
18610 void
18611 vat_api_hookup (vat_main_t * vam)
18612 {
18613 #define _(N,n)                                                  \
18614     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18615                            vl_api_##n##_t_handler_uni,          \
18616                            vl_noop_handler,                     \
18617                            vl_api_##n##_t_endian,               \
18618                            vl_api_##n##_t_print,                \
18619                            sizeof(vl_api_##n##_t), 1);
18620   foreach_vpe_api_reply_msg;
18621 #undef _
18622
18623 #if DPDK > 0
18624 #define _(N,n)                                                  \
18625     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18626                            vl_api_##n##_t_handler_uni,          \
18627                            vl_noop_handler,                     \
18628                            vl_api_##n##_t_endian,               \
18629                            vl_api_##n##_t_print,                \
18630                            sizeof(vl_api_##n##_t), 1);
18631   foreach_vpe_dpdk_api_reply_msg;
18632 #undef _
18633 #endif
18634
18635 #if (VPP_API_TEST_BUILTIN==0)
18636   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18637 #endif
18638
18639   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18640
18641   vam->function_by_name = hash_create_string (0, sizeof (uword));
18642
18643   vam->help_by_name = hash_create_string (0, sizeof (uword));
18644
18645   /* API messages we can send */
18646 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18647   foreach_vpe_api_msg;
18648 #undef _
18649 #if DPDK >0
18650 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18651   foreach_vpe_dpdk_api_msg;
18652 #undef _
18653 #endif
18654
18655   /* Help strings */
18656 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18657   foreach_vpe_api_msg;
18658 #undef _
18659 #if DPDK >0
18660 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18661   foreach_vpe_dpdk_api_msg;
18662 #undef _
18663 #endif
18664
18665   /* CLI functions */
18666 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18667   foreach_cli_function;
18668 #undef _
18669
18670   /* Help strings */
18671 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18672   foreach_cli_function;
18673 #undef _
18674 }
18675
18676 /*
18677  * fd.io coding-style-patch-verification: ON
18678  *
18679  * Local Variables:
18680  * eval: (c-set-style "gnu")
18681  * End:
18682  */