l2fib: MAC: Fix uint64 to u8 byte array
[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 <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   return vl_socket_client_connect
91     (&vam->socket_client_main, (char *) vam->socket_name,
92      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 void
102 vl_socket_client_read_reply (socket_client_main_t * scm)
103 {
104 };
105 #endif
106
107
108 f64
109 vat_time_now (vat_main_t * vam)
110 {
111 #if VPP_API_TEST_BUILTIN
112   return vlib_time_now (vam->vlib_main);
113 #else
114   return clib_time_now (&vam->clib_time);
115 #endif
116 }
117
118 void
119 errmsg (char *fmt, ...)
120 {
121   vat_main_t *vam = &vat_main;
122   va_list va;
123   u8 *s;
124
125   va_start (va, fmt);
126   s = va_format (0, fmt, &va);
127   va_end (va);
128
129   vec_add1 (s, 0);
130
131 #if VPP_API_TEST_BUILTIN
132   vlib_cli_output (vam->vlib_main, (char *) s);
133 #else
134   {
135     if (vam->ifp != stdin)
136       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
137                vam->input_line_number);
138     fformat (vam->ofp, (char *) s);
139     fflush (vam->ofp);
140   }
141 #endif
142
143   vec_free (s);
144 }
145
146 #if VPP_API_TEST_BUILTIN == 0
147 static uword
148 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
149 {
150   vat_main_t *vam = va_arg (*args, vat_main_t *);
151   u32 *result = va_arg (*args, u32 *);
152   u8 *if_name;
153   uword *p;
154
155   if (!unformat (input, "%s", &if_name))
156     return 0;
157
158   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
159   if (p == 0)
160     return 0;
161   *result = p[0];
162   return 1;
163 }
164
165 /* Parse an IP4 address %d.%d.%d.%d. */
166 uword
167 unformat_ip4_address (unformat_input_t * input, va_list * args)
168 {
169   u8 *result = va_arg (*args, u8 *);
170   unsigned a[4];
171
172   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
173     return 0;
174
175   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
176     return 0;
177
178   result[0] = a[0];
179   result[1] = a[1];
180   result[2] = a[2];
181   result[3] = a[3];
182
183   return 1;
184 }
185
186 uword
187 unformat_ethernet_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   u32 i, a[6];
191
192   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
193                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
194     return 0;
195
196   /* Check range. */
197   for (i = 0; i < 6; i++)
198     if (a[i] >= (1 << 8))
199       return 0;
200
201   for (i = 0; i < 6; i++)
202     result[i] = a[i];
203
204   return 1;
205 }
206
207 /* Returns ethernet type as an int in host byte order. */
208 uword
209 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
210                                         va_list * args)
211 {
212   u16 *result = va_arg (*args, u16 *);
213   int type;
214
215   /* Numeric type. */
216   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
217     {
218       if (type >= (1 << 16))
219         return 0;
220       *result = type;
221       return 1;
222     }
223   return 0;
224 }
225
226 /* Parse an IP6 address. */
227 uword
228 unformat_ip6_address (unformat_input_t * input, va_list * args)
229 {
230   ip6_address_t *result = va_arg (*args, ip6_address_t *);
231   u16 hex_quads[8];
232   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
233   uword c, n_colon, double_colon_index;
234
235   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
236   double_colon_index = ARRAY_LEN (hex_quads);
237   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
238     {
239       hex_digit = 16;
240       if (c >= '0' && c <= '9')
241         hex_digit = c - '0';
242       else if (c >= 'a' && c <= 'f')
243         hex_digit = c + 10 - 'a';
244       else if (c >= 'A' && c <= 'F')
245         hex_digit = c + 10 - 'A';
246       else if (c == ':' && n_colon < 2)
247         n_colon++;
248       else
249         {
250           unformat_put_input (input);
251           break;
252         }
253
254       /* Too many hex quads. */
255       if (n_hex_quads >= ARRAY_LEN (hex_quads))
256         return 0;
257
258       if (hex_digit < 16)
259         {
260           hex_quad = (hex_quad << 4) | hex_digit;
261
262           /* Hex quad must fit in 16 bits. */
263           if (n_hex_digits >= 4)
264             return 0;
265
266           n_colon = 0;
267           n_hex_digits++;
268         }
269
270       /* Save position of :: */
271       if (n_colon == 2)
272         {
273           /* More than one :: ? */
274           if (double_colon_index < ARRAY_LEN (hex_quads))
275             return 0;
276           double_colon_index = n_hex_quads;
277         }
278
279       if (n_colon > 0 && n_hex_digits > 0)
280         {
281           hex_quads[n_hex_quads++] = hex_quad;
282           hex_quad = 0;
283           n_hex_digits = 0;
284         }
285     }
286
287   if (n_hex_digits > 0)
288     hex_quads[n_hex_quads++] = hex_quad;
289
290   {
291     word i;
292
293     /* Expand :: to appropriate number of zero hex quads. */
294     if (double_colon_index < ARRAY_LEN (hex_quads))
295       {
296         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
297
298         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
299           hex_quads[n_zero + i] = hex_quads[i];
300
301         for (i = 0; i < n_zero; i++)
302           hex_quads[double_colon_index + i] = 0;
303
304         n_hex_quads = ARRAY_LEN (hex_quads);
305       }
306
307     /* Too few hex quads given. */
308     if (n_hex_quads < ARRAY_LEN (hex_quads))
309       return 0;
310
311     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
312       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
313
314     return 1;
315   }
316 }
317
318 uword
319 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
320 {
321   u32 *r = va_arg (*args, u32 *);
322
323   if (0);
324 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
325   foreach_ipsec_policy_action
326 #undef _
327     else
328     return 0;
329   return 1;
330 }
331
332 uword
333 unformat_ipsec_crypto_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_CRYPTO_ALG_##f;
339   foreach_ipsec_crypto_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_crypto_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_CRYPTO_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_crypto_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ipsec_integ_alg (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 = IPSEC_INTEG_ALG_##f;
370   foreach_ipsec_integ_alg
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 u8 *
378 format_ipsec_integ_alg (u8 * s, va_list * args)
379 {
380   u32 i = va_arg (*args, u32);
381   u8 *t = 0;
382
383   switch (i)
384     {
385 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
386       foreach_ipsec_integ_alg
387 #undef _
388     default:
389       return format (s, "unknown");
390     }
391   return format (s, "%s", t);
392 }
393
394 uword
395 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
396 {
397   u32 *r = va_arg (*args, u32 *);
398
399   if (0);
400 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
401   foreach_ikev2_auth_method
402 #undef _
403     else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
410 {
411   u32 *r = va_arg (*args, u32 *);
412
413   if (0);
414 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
415   foreach_ikev2_id_type
416 #undef _
417     else
418     return 0;
419   return 1;
420 }
421 #else /* VPP_API_TEST_BUILTIN == 1 */
422 static uword
423 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
424 {
425   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
426   vnet_main_t *vnm = vnet_get_main ();
427   u32 *result = va_arg (*args, u32 *);
428   u32 sw_if_index;
429
430   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
431     return 0;
432
433   *result = sw_if_index;
434   return 1;
435 }
436 #endif /* VPP_API_TEST_BUILTIN */
437
438 static uword
439 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
440 {
441   u8 *r = va_arg (*args, u8 *);
442
443   if (unformat (input, "kbps"))
444     *r = SSE2_QOS_RATE_KBPS;
445   else if (unformat (input, "pps"))
446     *r = SSE2_QOS_RATE_PPS;
447   else
448     return 0;
449   return 1;
450 }
451
452 static uword
453 unformat_policer_round_type (unformat_input_t * input, va_list * args)
454 {
455   u8 *r = va_arg (*args, u8 *);
456
457   if (unformat (input, "closest"))
458     *r = SSE2_QOS_ROUND_TO_CLOSEST;
459   else if (unformat (input, "up"))
460     *r = SSE2_QOS_ROUND_TO_UP;
461   else if (unformat (input, "down"))
462     *r = SSE2_QOS_ROUND_TO_DOWN;
463   else
464     return 0;
465   return 1;
466 }
467
468 static uword
469 unformat_policer_type (unformat_input_t * input, va_list * args)
470 {
471   u8 *r = va_arg (*args, u8 *);
472
473   if (unformat (input, "1r2c"))
474     *r = SSE2_QOS_POLICER_TYPE_1R2C;
475   else if (unformat (input, "1r3c"))
476     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
477   else if (unformat (input, "2r3c-2698"))
478     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
479   else if (unformat (input, "2r3c-4115"))
480     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
481   else if (unformat (input, "2r3c-mef5cf1"))
482     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_dscp (unformat_input_t * input, va_list * va)
490 {
491   u8 *r = va_arg (*va, u8 *);
492
493   if (0);
494 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
495   foreach_vnet_dscp
496 #undef _
497     else
498     return 0;
499   return 1;
500 }
501
502 static uword
503 unformat_policer_action_type (unformat_input_t * input, va_list * va)
504 {
505   sse2_qos_pol_action_params_st *a
506     = va_arg (*va, sse2_qos_pol_action_params_st *);
507
508   if (unformat (input, "drop"))
509     a->action_type = SSE2_QOS_ACTION_DROP;
510   else if (unformat (input, "transmit"))
511     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
512   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
513     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
514   else
515     return 0;
516   return 1;
517 }
518
519 static uword
520 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
521 {
522   u32 *r = va_arg (*va, u32 *);
523   u32 tid;
524
525   if (unformat (input, "ip4"))
526     tid = POLICER_CLASSIFY_TABLE_IP4;
527   else if (unformat (input, "ip6"))
528     tid = POLICER_CLASSIFY_TABLE_IP6;
529   else if (unformat (input, "l2"))
530     tid = POLICER_CLASSIFY_TABLE_L2;
531   else
532     return 0;
533
534   *r = tid;
535   return 1;
536 }
537
538 static uword
539 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
540 {
541   u32 *r = va_arg (*va, u32 *);
542   u32 tid;
543
544   if (unformat (input, "ip4"))
545     tid = FLOW_CLASSIFY_TABLE_IP4;
546   else if (unformat (input, "ip6"))
547     tid = FLOW_CLASSIFY_TABLE_IP6;
548   else
549     return 0;
550
551   *r = tid;
552   return 1;
553 }
554
555 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
556 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
557 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
558 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
559
560 #if (VPP_API_TEST_BUILTIN==0)
561 uword
562 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
563 {
564   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
565   mfib_itf_attribute_t attr;
566
567   old = *iflags;
568   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
569   {
570     if (unformat (input, mfib_itf_flag_long_names[attr]))
571       *iflags |= (1 << attr);
572   }
573   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
574   {
575     if (unformat (input, mfib_itf_flag_names[attr]))
576       *iflags |= (1 << attr);
577   }
578
579   return (old == *iflags ? 0 : 1);
580 }
581
582 uword
583 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
586   mfib_entry_attribute_t attr;
587
588   old = *eflags;
589   FOR_EACH_MFIB_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_flag_long_names[attr]))
592       *eflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_flag_names[attr]))
597       *eflags |= (1 << attr);
598   }
599
600   return (old == *eflags ? 0 : 1);
601 }
602
603 u8 *
604 format_ip4_address (u8 * s, va_list * args)
605 {
606   u8 *a = va_arg (*args, u8 *);
607   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
608 }
609
610 u8 *
611 format_ip6_address (u8 * s, va_list * args)
612 {
613   ip6_address_t *a = va_arg (*args, ip6_address_t *);
614   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
615
616   i_max_n_zero = ARRAY_LEN (a->as_u16);
617   max_n_zeros = 0;
618   i_first_zero = i_max_n_zero;
619   n_zeros = 0;
620   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
621     {
622       u32 is_zero = a->as_u16[i] == 0;
623       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
624         {
625           i_first_zero = i;
626           n_zeros = 0;
627         }
628       n_zeros += is_zero;
629       if ((!is_zero && n_zeros > max_n_zeros)
630           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
631         {
632           i_max_n_zero = i_first_zero;
633           max_n_zeros = n_zeros;
634           i_first_zero = ARRAY_LEN (a->as_u16);
635           n_zeros = 0;
636         }
637     }
638
639   last_double_colon = 0;
640   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
641     {
642       if (i == i_max_n_zero && max_n_zeros > 1)
643         {
644           s = format (s, "::");
645           i += max_n_zeros - 1;
646           last_double_colon = 1;
647         }
648       else
649         {
650           s = format (s, "%s%x",
651                       (last_double_colon || i == 0) ? "" : ":",
652                       clib_net_to_host_u16 (a->as_u16[i]));
653           last_double_colon = 0;
654         }
655     }
656
657   return s;
658 }
659
660 /* Format an IP46 address. */
661 u8 *
662 format_ip46_address (u8 * s, va_list * args)
663 {
664   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
665   ip46_type_t type = va_arg (*args, ip46_type_t);
666   int is_ip4 = 1;
667
668   switch (type)
669     {
670     case IP46_TYPE_ANY:
671       is_ip4 = ip46_address_is_ip4 (ip46);
672       break;
673     case IP46_TYPE_IP4:
674       is_ip4 = 1;
675       break;
676     case IP46_TYPE_IP6:
677       is_ip4 = 0;
678       break;
679     }
680
681   return is_ip4 ?
682     format (s, "%U", format_ip4_address, &ip46->ip4) :
683     format (s, "%U", format_ip6_address, &ip46->ip6);
684 }
685
686 u8 *
687 format_ethernet_address (u8 * s, va_list * args)
688 {
689   u8 *a = va_arg (*args, u8 *);
690
691   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
692                  a[0], a[1], a[2], a[3], a[4], a[5]);
693 }
694 #endif
695
696 static void
697 increment_v4_address (ip4_address_t * a)
698 {
699   u32 v;
700
701   v = ntohl (a->as_u32) + 1;
702   a->as_u32 = ntohl (v);
703 }
704
705 static void
706 increment_v6_address (ip6_address_t * a)
707 {
708   u64 v0, v1;
709
710   v0 = clib_net_to_host_u64 (a->as_u64[0]);
711   v1 = clib_net_to_host_u64 (a->as_u64[1]);
712
713   v1 += 1;
714   if (v1 == 0)
715     v0 += 1;
716   a->as_u64[0] = clib_net_to_host_u64 (v0);
717   a->as_u64[1] = clib_net_to_host_u64 (v1);
718 }
719
720 static void
721 increment_mac_address (u8 * mac)
722 {
723   u64 tmp = *((u64 *) mac);
724   tmp = clib_net_to_host_u64 (tmp);
725   tmp += 1 << 16;               /* skip unused (least significant) octets */
726   tmp = clib_host_to_net_u64 (tmp);
727
728   clib_memcpy (mac, &tmp, 6);
729 }
730
731 static void vl_api_create_loopback_reply_t_handler
732   (vl_api_create_loopback_reply_t * mp)
733 {
734   vat_main_t *vam = &vat_main;
735   i32 retval = ntohl (mp->retval);
736
737   vam->retval = retval;
738   vam->regenerate_interface_table = 1;
739   vam->sw_if_index = ntohl (mp->sw_if_index);
740   vam->result_ready = 1;
741 }
742
743 static void vl_api_create_loopback_reply_t_handler_json
744   (vl_api_create_loopback_reply_t * mp)
745 {
746   vat_main_t *vam = &vat_main;
747   vat_json_node_t node;
748
749   vat_json_init_object (&node);
750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
752
753   vat_json_print (vam->ofp, &node);
754   vat_json_free (&node);
755   vam->retval = ntohl (mp->retval);
756   vam->result_ready = 1;
757 }
758
759 static void vl_api_create_loopback_instance_reply_t_handler
760   (vl_api_create_loopback_instance_reply_t * mp)
761 {
762   vat_main_t *vam = &vat_main;
763   i32 retval = ntohl (mp->retval);
764
765   vam->retval = retval;
766   vam->regenerate_interface_table = 1;
767   vam->sw_if_index = ntohl (mp->sw_if_index);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_loopback_instance_reply_t_handler_json
772   (vl_api_create_loopback_instance_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   vat_json_node_t node;
776
777   vat_json_init_object (&node);
778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
779   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
780
781   vat_json_print (vam->ofp, &node);
782   vat_json_free (&node);
783   vam->retval = ntohl (mp->retval);
784   vam->result_ready = 1;
785 }
786
787 static void vl_api_af_packet_create_reply_t_handler
788   (vl_api_af_packet_create_reply_t * mp)
789 {
790   vat_main_t *vam = &vat_main;
791   i32 retval = ntohl (mp->retval);
792
793   vam->retval = retval;
794   vam->regenerate_interface_table = 1;
795   vam->sw_if_index = ntohl (mp->sw_if_index);
796   vam->result_ready = 1;
797 }
798
799 static void vl_api_af_packet_create_reply_t_handler_json
800   (vl_api_af_packet_create_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   vat_json_node_t node;
804
805   vat_json_init_object (&node);
806   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
807   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
808
809   vat_json_print (vam->ofp, &node);
810   vat_json_free (&node);
811
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_create_vlan_subif_reply_t_handler
817   (vl_api_create_vlan_subif_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_create_vlan_subif_reply_t_handler_json
829   (vl_api_create_vlan_subif_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_subif_reply_t_handler
846   (vl_api_create_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_subif_reply_t_handler_json
858   (vl_api_create_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_interface_name_renumber_reply_t_handler
875   (vl_api_interface_name_renumber_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->result_ready = 1;
883 }
884
885 static void vl_api_interface_name_renumber_reply_t_handler_json
886   (vl_api_interface_name_renumber_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890
891   vat_json_init_object (&node);
892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
893
894   vat_json_print (vam->ofp, &node);
895   vat_json_free (&node);
896
897   vam->retval = ntohl (mp->retval);
898   vam->result_ready = 1;
899 }
900
901 /*
902  * Special-case: build the interface table, maintain
903  * the next loopback sw_if_index vbl.
904  */
905 static void vl_api_sw_interface_details_t_handler
906   (vl_api_sw_interface_details_t * mp)
907 {
908   vat_main_t *vam = &vat_main;
909   u8 *s = format (0, "%s%c", mp->interface_name, 0);
910
911   hash_set_mem (vam->sw_if_index_by_interface_name, s,
912                 ntohl (mp->sw_if_index));
913
914   /* In sub interface case, fill the sub interface table entry */
915   if (mp->sw_if_index != mp->sup_sw_if_index)
916     {
917       sw_interface_subif_t *sub = NULL;
918
919       vec_add2 (vam->sw_if_subif_table, sub, 1);
920
921       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
922       strncpy ((char *) sub->interface_name, (char *) s,
923                vec_len (sub->interface_name));
924       sub->sw_if_index = ntohl (mp->sw_if_index);
925       sub->sub_id = ntohl (mp->sub_id);
926
927       sub->sub_dot1ad = mp->sub_dot1ad;
928       sub->sub_number_of_tags = mp->sub_number_of_tags;
929       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
930       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
931       sub->sub_exact_match = mp->sub_exact_match;
932       sub->sub_default = mp->sub_default;
933       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
934       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
935
936       /* vlan tag rewrite */
937       sub->vtr_op = ntohl (mp->vtr_op);
938       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
939       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
940       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
941     }
942 }
943
944 static void vl_api_sw_interface_details_t_handler_json
945   (vl_api_sw_interface_details_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   vat_json_node_t *node = NULL;
949
950   if (VAT_JSON_ARRAY != vam->json_tree.type)
951     {
952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
953       vat_json_init_array (&vam->json_tree);
954     }
955   node = vat_json_array_add (&vam->json_tree);
956
957   vat_json_init_object (node);
958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
959   vat_json_object_add_uint (node, "sup_sw_if_index",
960                             ntohl (mp->sup_sw_if_index));
961   vat_json_object_add_uint (node, "l2_address_length",
962                             ntohl (mp->l2_address_length));
963   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
964                              sizeof (mp->l2_address));
965   vat_json_object_add_string_copy (node, "interface_name",
966                                    mp->interface_name);
967   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
968   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
969   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
970   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
971   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
972   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
973   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
974   vat_json_object_add_uint (node, "sub_number_of_tags",
975                             mp->sub_number_of_tags);
976   vat_json_object_add_uint (node, "sub_outer_vlan_id",
977                             ntohs (mp->sub_outer_vlan_id));
978   vat_json_object_add_uint (node, "sub_inner_vlan_id",
979                             ntohs (mp->sub_inner_vlan_id));
980   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
981   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
982   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
983                             mp->sub_outer_vlan_id_any);
984   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
985                             mp->sub_inner_vlan_id_any);
986   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
987   vat_json_object_add_uint (node, "vtr_push_dot1q",
988                             ntohl (mp->vtr_push_dot1q));
989   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
990   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
991   if (mp->sub_dot1ah)
992     {
993       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
994                                        format (0, "%U",
995                                                format_ethernet_address,
996                                                &mp->b_dmac));
997       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
998                                        format (0, "%U",
999                                                format_ethernet_address,
1000                                                &mp->b_smac));
1001       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1002       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1003     }
1004 }
1005
1006 #if VPP_API_TEST_BUILTIN == 0
1007 static void vl_api_sw_interface_event_t_handler
1008   (vl_api_sw_interface_event_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   if (vam->interface_event_display)
1012     errmsg ("interface flags: sw_if_index %d %s %s",
1013             ntohl (mp->sw_if_index),
1014             mp->admin_up_down ? "admin-up" : "admin-down",
1015             mp->link_up_down ? "link-up" : "link-down");
1016 }
1017 #endif
1018
1019 static void vl_api_sw_interface_event_t_handler_json
1020   (vl_api_sw_interface_event_t * mp)
1021 {
1022   /* JSON output not supported */
1023 }
1024
1025 static void
1026 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030
1031   vam->retval = retval;
1032   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033   vam->result_ready = 1;
1034 }
1035
1036 static void
1037 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t node;
1041   api_main_t *am = &api_main;
1042   void *oldheap;
1043   u8 *reply;
1044
1045   vat_json_init_object (&node);
1046   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1047   vat_json_object_add_uint (&node, "reply_in_shmem",
1048                             ntohl (mp->reply_in_shmem));
1049   /* Toss the shared-memory original... */
1050   pthread_mutex_lock (&am->vlib_rp->mutex);
1051   oldheap = svm_push_data_heap (am->vlib_rp);
1052
1053   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1054   vec_free (reply);
1055
1056   svm_pop_heap (oldheap);
1057   pthread_mutex_unlock (&am->vlib_rp->mutex);
1058
1059   vat_json_print (vam->ofp, &node);
1060   vat_json_free (&node);
1061
1062   vam->retval = ntohl (mp->retval);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   i32 retval = ntohl (mp->retval);
1071   u32 length = ntohl (mp->length);
1072
1073   vec_reset_length (vam->cmd_reply);
1074
1075   vam->retval = retval;
1076   if (retval == 0)
1077     {
1078       vec_validate (vam->cmd_reply, length);
1079       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1080       vam->cmd_reply[length] = 0;
1081     }
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vec_reset_length (vam->cmd_reply);
1092
1093   vat_json_init_object (&node);
1094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1095   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1096
1097   vat_json_print (vam->ofp, &node);
1098   vat_json_free (&node);
1099
1100   vam->retval = ntohl (mp->retval);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void vl_api_classify_add_del_table_reply_t_handler
1105   (vl_api_classify_add_del_table_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   i32 retval = ntohl (mp->retval);
1109   if (vam->async_mode)
1110     {
1111       vam->async_errors += (retval < 0);
1112     }
1113   else
1114     {
1115       vam->retval = retval;
1116       if (retval == 0 &&
1117           ((mp->new_table_index != 0xFFFFFFFF) ||
1118            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1119            (mp->match_n_vectors != 0xFFFFFFFF)))
1120         /*
1121          * Note: this is just barely thread-safe, depends on
1122          * the main thread spinning waiting for an answer...
1123          */
1124         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1125                 ntohl (mp->new_table_index),
1126                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1127       vam->result_ready = 1;
1128     }
1129 }
1130
1131 static void vl_api_classify_add_del_table_reply_t_handler_json
1132   (vl_api_classify_add_del_table_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "new_table_index",
1140                             ntohl (mp->new_table_index));
1141   vat_json_object_add_uint (&node, "skip_n_vectors",
1142                             ntohl (mp->skip_n_vectors));
1143   vat_json_object_add_uint (&node, "match_n_vectors",
1144                             ntohl (mp->match_n_vectors));
1145
1146   vat_json_print (vam->ofp, &node);
1147   vat_json_free (&node);
1148
1149   vam->retval = ntohl (mp->retval);
1150   vam->result_ready = 1;
1151 }
1152
1153 static void vl_api_get_node_index_reply_t_handler
1154   (vl_api_get_node_index_reply_t * mp)
1155 {
1156   vat_main_t *vam = &vat_main;
1157   i32 retval = ntohl (mp->retval);
1158   if (vam->async_mode)
1159     {
1160       vam->async_errors += (retval < 0);
1161     }
1162   else
1163     {
1164       vam->retval = retval;
1165       if (retval == 0)
1166         errmsg ("node index %d", ntohl (mp->node_index));
1167       vam->result_ready = 1;
1168     }
1169 }
1170
1171 static void vl_api_get_node_index_reply_t_handler_json
1172   (vl_api_get_node_index_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176
1177   vat_json_init_object (&node);
1178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1179   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1180
1181   vat_json_print (vam->ofp, &node);
1182   vat_json_free (&node);
1183
1184   vam->retval = ntohl (mp->retval);
1185   vam->result_ready = 1;
1186 }
1187
1188 static void vl_api_get_next_index_reply_t_handler
1189   (vl_api_get_next_index_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   i32 retval = ntohl (mp->retval);
1193   if (vam->async_mode)
1194     {
1195       vam->async_errors += (retval < 0);
1196     }
1197   else
1198     {
1199       vam->retval = retval;
1200       if (retval == 0)
1201         errmsg ("next node index %d", ntohl (mp->next_index));
1202       vam->result_ready = 1;
1203     }
1204 }
1205
1206 static void vl_api_get_next_index_reply_t_handler_json
1207   (vl_api_get_next_index_reply_t * mp)
1208 {
1209   vat_main_t *vam = &vat_main;
1210   vat_json_node_t node;
1211
1212   vat_json_init_object (&node);
1213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1214   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_add_node_next_reply_t_handler
1224   (vl_api_add_node_next_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("next index %d", ntohl (mp->next_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_add_node_next_reply_t_handler_json
1242   (vl_api_add_node_next_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_show_version_reply_t_handler
1259   (vl_api_show_version_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263
1264   if (retval >= 0)
1265     {
1266       errmsg ("        program: %s", mp->program);
1267       errmsg ("        version: %s", mp->version);
1268       errmsg ("     build date: %s", mp->build_date);
1269       errmsg ("build directory: %s", mp->build_directory);
1270     }
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void vl_api_show_version_reply_t_handler_json
1276   (vl_api_show_version_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t node;
1280
1281   vat_json_init_object (&node);
1282   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1283   vat_json_object_add_string_copy (&node, "program", mp->program);
1284   vat_json_object_add_string_copy (&node, "version", mp->version);
1285   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1286   vat_json_object_add_string_copy (&node, "build_directory",
1287                                    mp->build_directory);
1288
1289   vat_json_print (vam->ofp, &node);
1290   vat_json_free (&node);
1291
1292   vam->retval = ntohl (mp->retval);
1293   vam->result_ready = 1;
1294 }
1295
1296 static void
1297 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1298 {
1299   u32 sw_if_index = ntohl (mp->sw_if_index);
1300   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1301           mp->mac_ip ? "mac/ip binding" : "address resolution",
1302           ntohl (mp->pid), format_ip4_address, &mp->address,
1303           format_ethernet_address, mp->new_mac, sw_if_index);
1304 }
1305
1306 static void
1307 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1308 {
1309   /* JSON output not supported */
1310 }
1311
1312 static void
1313 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1314 {
1315   u32 sw_if_index = ntohl (mp->sw_if_index);
1316   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1317           mp->mac_ip ? "mac/ip binding" : "address resolution",
1318           ntohl (mp->pid), format_ip6_address, mp->address,
1319           format_ethernet_address, mp->new_mac, sw_if_index);
1320 }
1321
1322 static void
1323 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1324 {
1325   /* JSON output not supported */
1326 }
1327
1328 static void
1329 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1330 {
1331   u32 n_macs = ntohl (mp->n_macs);
1332   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1333           ntohl (mp->pid), mp->client_index, n_macs);
1334   int i;
1335   for (i = 0; i < n_macs; i++)
1336     {
1337       vl_api_mac_entry_t *mac = &mp->mac[i];
1338       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1339               i + 1, ntohl (mac->sw_if_index),
1340               format_ethernet_address, mac->mac_addr, mac->is_del);
1341       if (i == 1000)
1342         break;
1343     }
1344 }
1345
1346 static void
1347 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1348 {
1349   /* JSON output not supported */
1350 }
1351
1352 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1353 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1354
1355 /*
1356  * Special-case: build the bridge domain table, maintain
1357  * the next bd id vbl.
1358  */
1359 static void vl_api_bridge_domain_details_t_handler
1360   (vl_api_bridge_domain_details_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1364   int i;
1365
1366   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1367          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1368
1369   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1370          ntohl (mp->bd_id), mp->learn, mp->forward,
1371          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1372
1373   if (n_sw_ifs)
1374     {
1375       vl_api_bridge_domain_sw_if_t *sw_ifs;
1376       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1377              "Interface Name");
1378
1379       sw_ifs = mp->sw_if_details;
1380       for (i = 0; i < n_sw_ifs; i++)
1381         {
1382           u8 *sw_if_name = 0;
1383           u32 sw_if_index;
1384           hash_pair_t *p;
1385
1386           sw_if_index = ntohl (sw_ifs->sw_if_index);
1387
1388           /* *INDENT-OFF* */
1389           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1390                              ({
1391                                if ((u32) p->value[0] == sw_if_index)
1392                                  {
1393                                    sw_if_name = (u8 *)(p->key);
1394                                    break;
1395                                  }
1396                              }));
1397           /* *INDENT-ON* */
1398           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1399                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1400                  "sw_if_index not found!");
1401
1402           sw_ifs++;
1403         }
1404     }
1405 }
1406
1407 static void vl_api_bridge_domain_details_t_handler_json
1408   (vl_api_bridge_domain_details_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t *node, *array = NULL;
1412   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1413
1414   if (VAT_JSON_ARRAY != vam->json_tree.type)
1415     {
1416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1417       vat_json_init_array (&vam->json_tree);
1418     }
1419   node = vat_json_array_add (&vam->json_tree);
1420
1421   vat_json_init_object (node);
1422   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1423   vat_json_object_add_uint (node, "flood", mp->flood);
1424   vat_json_object_add_uint (node, "forward", mp->forward);
1425   vat_json_object_add_uint (node, "learn", mp->learn);
1426   vat_json_object_add_uint (node, "bvi_sw_if_index",
1427                             ntohl (mp->bvi_sw_if_index));
1428   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1429   array = vat_json_object_add (node, "sw_if");
1430   vat_json_init_array (array);
1431
1432
1433
1434   if (n_sw_ifs)
1435     {
1436       vl_api_bridge_domain_sw_if_t *sw_ifs;
1437       int i;
1438
1439       sw_ifs = mp->sw_if_details;
1440       for (i = 0; i < n_sw_ifs; i++)
1441         {
1442           node = vat_json_array_add (array);
1443           vat_json_init_object (node);
1444           vat_json_object_add_uint (node, "sw_if_index",
1445                                     ntohl (sw_ifs->sw_if_index));
1446           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1447           sw_ifs++;
1448         }
1449     }
1450 }
1451
1452 static void vl_api_control_ping_reply_t_handler
1453   (vl_api_control_ping_reply_t * mp)
1454 {
1455   vat_main_t *vam = &vat_main;
1456   i32 retval = ntohl (mp->retval);
1457   if (vam->async_mode)
1458     {
1459       vam->async_errors += (retval < 0);
1460     }
1461   else
1462     {
1463       vam->retval = retval;
1464       vam->result_ready = 1;
1465     }
1466   vam->socket_client_main.control_pings_outstanding--;
1467 }
1468
1469 static void vl_api_control_ping_reply_t_handler_json
1470   (vl_api_control_ping_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474
1475   if (VAT_JSON_NONE != vam->json_tree.type)
1476     {
1477       vat_json_print (vam->ofp, &vam->json_tree);
1478       vat_json_free (&vam->json_tree);
1479       vam->json_tree.type = VAT_JSON_NONE;
1480     }
1481   else
1482     {
1483       /* just print [] */
1484       vat_json_init_array (&vam->json_tree);
1485       vat_json_print (vam->ofp, &vam->json_tree);
1486       vam->json_tree.type = VAT_JSON_NONE;
1487     }
1488
1489   vam->retval = retval;
1490   vam->result_ready = 1;
1491 }
1492
1493 static void
1494   vl_api_bridge_domain_set_mac_age_reply_t_handler
1495   (vl_api_bridge_domain_set_mac_age_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->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518
1519   vat_json_print (vam->ofp, &node);
1520   vat_json_free (&node);
1521
1522   vam->retval = ntohl (mp->retval);
1523   vam->result_ready = 1;
1524 }
1525
1526 static void
1527 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   i32 retval = ntohl (mp->retval);
1531   if (vam->async_mode)
1532     {
1533       vam->async_errors += (retval < 0);
1534     }
1535   else
1536     {
1537       vam->retval = retval;
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_l2_flags_reply_t_handler_json
1543   (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1551                             ntohl (mp->resulting_feature_bitmap));
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_bridge_flags_reply_t_handler
1561   (vl_api_bridge_flags_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_bridge_flags_reply_t_handler_json
1577   (vl_api_bridge_flags_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, "resulting_feature_bitmap",
1585                             ntohl (mp->resulting_feature_bitmap));
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_tap_connect_reply_t_handler
1595   (vl_api_tap_connect_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
1612 static void vl_api_tap_connect_reply_t_handler_json
1613   (vl_api_tap_connect_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   vat_json_node_t node;
1617
1618   vat_json_init_object (&node);
1619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627
1628 }
1629
1630 static void
1631 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->sw_if_index = ntohl (mp->sw_if_index);
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_tap_modify_reply_t_handler_json
1648   (vl_api_tap_modify_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_tap_delete_reply_t_handler_json
1681   (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_mpls_tunnel_add_del_reply_t_handler
1697   (vl_api_mpls_tunnel_add_del_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->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1713   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1721                             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_l2tpv3_create_tunnel_reply_t_handler
1731   (vl_api_l2tpv3_create_tunnel_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_l2tpv3_create_tunnel_reply_t_handler_json
1748   (vl_api_l2tpv3_create_tunnel_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_gpe_add_del_fwd_entry_reply_t_handler
1765   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1781   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "fwd_entry_index",
1789                             clib_net_to_host_u32 (mp->fwd_entry_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 u8 *
1799 format_lisp_transport_protocol (u8 * s, va_list * args)
1800 {
1801   u32 proto = va_arg (*args, u32);
1802
1803   switch (proto)
1804     {
1805     case 1:
1806       return format (s, "udp");
1807     case 2:
1808       return format (s, "api");
1809     default:
1810       return 0;
1811     }
1812   return 0;
1813 }
1814
1815 static void vl_api_one_get_transport_protocol_reply_t_handler
1816   (vl_api_one_get_transport_protocol_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       u32 proto = mp->protocol;
1827       print (vam->ofp, "Transport protocol: %U",
1828              format_lisp_transport_protocol, proto);
1829       vam->retval = retval;
1830       vam->result_ready = 1;
1831     }
1832 }
1833
1834 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1835   (vl_api_one_get_transport_protocol_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   vat_json_node_t node;
1839   u8 *s;
1840
1841   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1842   vec_add1 (s, 0);
1843
1844   vat_json_init_object (&node);
1845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1846   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1847
1848   vec_free (s);
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_one_add_del_locator_set_reply_t_handler
1857   (vl_api_one_add_del_locator_set_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->result_ready = 1;
1869     }
1870 }
1871
1872 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1873   (vl_api_one_add_del_locator_set_reply_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   vat_json_node_t node;
1877
1878   vat_json_init_object (&node);
1879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1880   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1881
1882   vat_json_print (vam->ofp, &node);
1883   vat_json_free (&node);
1884
1885   vam->retval = ntohl (mp->retval);
1886   vam->result_ready = 1;
1887 }
1888
1889 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1890   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   i32 retval = ntohl (mp->retval);
1894   if (vam->async_mode)
1895     {
1896       vam->async_errors += (retval < 0);
1897     }
1898   else
1899     {
1900       vam->retval = retval;
1901       vam->sw_if_index = ntohl (mp->sw_if_index);
1902       vam->result_ready = 1;
1903     }
1904 }
1905
1906 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1907   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t node;
1911
1912   vat_json_init_object (&node);
1913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1914   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1915
1916   vat_json_print (vam->ofp, &node);
1917   vat_json_free (&node);
1918
1919   vam->retval = ntohl (mp->retval);
1920   vam->result_ready = 1;
1921 }
1922
1923 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1924   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   i32 retval = ntohl (mp->retval);
1928   if (vam->async_mode)
1929     {
1930       vam->async_errors += (retval < 0);
1931     }
1932   else
1933     {
1934       vam->retval = retval;
1935       vam->sw_if_index = ntohl (mp->sw_if_index);
1936       vam->result_ready = 1;
1937     }
1938 }
1939
1940 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
1941   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1942 {
1943   vat_main_t *vam = &vat_main;
1944   vat_json_node_t node;
1945
1946   vat_json_init_object (&node);
1947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1948   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1949
1950   vat_json_print (vam->ofp, &node);
1951   vat_json_free (&node);
1952
1953   vam->retval = ntohl (mp->retval);
1954   vam->result_ready = 1;
1955 }
1956
1957 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1958   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   i32 retval = ntohl (mp->retval);
1962   if (vam->async_mode)
1963     {
1964       vam->async_errors += (retval < 0);
1965     }
1966   else
1967     {
1968       vam->retval = retval;
1969       vam->sw_if_index = ntohl (mp->sw_if_index);
1970       vam->result_ready = 1;
1971     }
1972 }
1973
1974 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1975   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   vat_json_node_t node;
1979
1980   vat_json_init_object (&node);
1981   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1982   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1983
1984   vat_json_print (vam->ofp, &node);
1985   vat_json_free (&node);
1986
1987   vam->retval = ntohl (mp->retval);
1988   vam->result_ready = 1;
1989 }
1990
1991 static void vl_api_gre_add_del_tunnel_reply_t_handler
1992   (vl_api_gre_add_del_tunnel_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   i32 retval = ntohl (mp->retval);
1996   if (vam->async_mode)
1997     {
1998       vam->async_errors += (retval < 0);
1999     }
2000   else
2001     {
2002       vam->retval = retval;
2003       vam->sw_if_index = ntohl (mp->sw_if_index);
2004       vam->result_ready = 1;
2005     }
2006 }
2007
2008 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2009   (vl_api_gre_add_del_tunnel_reply_t * mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   vat_json_node_t node;
2013
2014   vat_json_init_object (&node);
2015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2016   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2017
2018   vat_json_print (vam->ofp, &node);
2019   vat_json_free (&node);
2020
2021   vam->retval = ntohl (mp->retval);
2022   vam->result_ready = 1;
2023 }
2024
2025 static void vl_api_create_vhost_user_if_reply_t_handler
2026   (vl_api_create_vhost_user_if_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   i32 retval = ntohl (mp->retval);
2030   if (vam->async_mode)
2031     {
2032       vam->async_errors += (retval < 0);
2033     }
2034   else
2035     {
2036       vam->retval = retval;
2037       vam->sw_if_index = ntohl (mp->sw_if_index);
2038       vam->result_ready = 1;
2039     }
2040 }
2041
2042 static void vl_api_create_vhost_user_if_reply_t_handler_json
2043   (vl_api_create_vhost_user_if_reply_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vat_json_node_t node;
2047
2048   vat_json_init_object (&node);
2049   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2050   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2051
2052   vat_json_print (vam->ofp, &node);
2053   vat_json_free (&node);
2054
2055   vam->retval = ntohl (mp->retval);
2056   vam->result_ready = 1;
2057 }
2058
2059 static clib_error_t *
2060 receive_fd_msg (int socket_fd, int *my_fd)
2061 {
2062   char msgbuf[16];
2063   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2064   struct msghdr mh = { 0 };
2065   struct iovec iov[1];
2066   ssize_t size;
2067   struct ucred *cr = 0;
2068   struct cmsghdr *cmsg;
2069   pid_t pid __attribute__ ((unused));
2070   uid_t uid __attribute__ ((unused));
2071   gid_t gid __attribute__ ((unused));
2072
2073   iov[0].iov_base = msgbuf;
2074   iov[0].iov_len = 5;
2075   mh.msg_iov = iov;
2076   mh.msg_iovlen = 1;
2077   mh.msg_control = ctl;
2078   mh.msg_controllen = sizeof (ctl);
2079
2080   memset (ctl, 0, sizeof (ctl));
2081
2082   /* receive the incoming message */
2083   size = recvmsg (socket_fd, &mh, 0);
2084   if (size != 5)
2085     {
2086       return (size == 0) ? clib_error_return (0, "disconnected") :
2087         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2088                                 socket_fd);
2089     }
2090
2091   cmsg = CMSG_FIRSTHDR (&mh);
2092   while (cmsg)
2093     {
2094       if (cmsg->cmsg_level == SOL_SOCKET)
2095         {
2096           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2097             {
2098               cr = (struct ucred *) CMSG_DATA (cmsg);
2099               uid = cr->uid;
2100               gid = cr->gid;
2101               pid = cr->pid;
2102             }
2103           else if (cmsg->cmsg_type == SCM_RIGHTS)
2104             {
2105               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2106             }
2107         }
2108       cmsg = CMSG_NXTHDR (&mh, cmsg);
2109     }
2110   return 0;
2111 }
2112
2113 static void vl_api_memfd_segment_create_reply_t_handler
2114   (vl_api_memfd_segment_create_reply_t * mp)
2115 {
2116   /* Dont bother in the builtin version */
2117 #if VPP_API_TEST_BUILTIN == 0
2118   vat_main_t *vam = &vat_main;
2119   api_main_t *am = &api_main;
2120   socket_client_main_t *scm = &vam->socket_client_main;
2121   int my_fd = -1;
2122   clib_error_t *error;
2123   memfd_private_t memfd;
2124   i32 retval = ntohl (mp->retval);
2125
2126   if (retval == 0)
2127     {
2128       error = receive_fd_msg (scm->socket_fd, &my_fd);
2129       if (error)
2130         {
2131           retval = -99;
2132           goto out;
2133         }
2134
2135       memset (&memfd, 0, sizeof (memfd));
2136       memfd.fd = my_fd;
2137
2138       vam->client_index_invalid = 1;
2139
2140       /* Note: this closes memfd.fd */
2141       retval = memfd_slave_init (&memfd);
2142       if (retval)
2143         clib_warning ("WARNING: segment map returned %d", retval);
2144
2145       /* Pivot to the memory client segment that vpp just created */
2146
2147       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2148
2149       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2150
2151       vl_client_install_client_message_handlers ();
2152
2153       vl_client_connect_to_vlib_no_map ("pvt",
2154                                         "vpp_api_test(p)",
2155                                         32 /* input_queue_length */ );
2156       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2157
2158       vl_socket_client_enable_disable (&vam->socket_client_main,
2159                                        0 /* disable socket */ );
2160     }
2161
2162 out:
2163   if (vam->async_mode)
2164     {
2165       vam->async_errors += (retval < 0);
2166     }
2167   else
2168     {
2169       vam->retval = retval;
2170       vam->result_ready = 1;
2171     }
2172 #endif
2173 }
2174
2175 static void vl_api_memfd_segment_create_reply_t_handler_json
2176   (vl_api_memfd_segment_create_reply_t * mp)
2177 {
2178   clib_warning ("no");
2179 }
2180
2181 static void vl_api_dns_resolve_name_reply_t_handler
2182   (vl_api_dns_resolve_name_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->result_ready = 1;
2194
2195       if (retval == 0)
2196         {
2197           if (mp->ip4_set)
2198             clib_warning ("ip4 address %U", format_ip4_address,
2199                           (ip4_address_t *) mp->ip4_address);
2200           if (mp->ip6_set)
2201             clib_warning ("ip6 address %U", format_ip6_address,
2202                           (ip6_address_t *) mp->ip6_address);
2203         }
2204       else
2205         clib_warning ("retval %d", retval);
2206     }
2207 }
2208
2209 static void vl_api_dns_resolve_name_reply_t_handler_json
2210   (vl_api_dns_resolve_name_reply_t * mp)
2211 {
2212   clib_warning ("not implemented");
2213 }
2214
2215 static void vl_api_dns_resolve_ip_reply_t_handler
2216   (vl_api_dns_resolve_ip_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->result_ready = 1;
2228
2229       if (retval == 0)
2230         {
2231           clib_warning ("canonical name %s", mp->name);
2232         }
2233       else
2234         clib_warning ("retval %d", retval);
2235     }
2236 }
2237
2238 static void vl_api_dns_resolve_ip_reply_t_handler_json
2239   (vl_api_dns_resolve_ip_reply_t * mp)
2240 {
2241   clib_warning ("not implemented");
2242 }
2243
2244
2245 static void vl_api_ip_address_details_t_handler
2246   (vl_api_ip_address_details_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   static ip_address_details_t empty_ip_address_details = { {0} };
2250   ip_address_details_t *address = NULL;
2251   ip_details_t *current_ip_details = NULL;
2252   ip_details_t *details = NULL;
2253
2254   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2255
2256   if (!details || vam->current_sw_if_index >= vec_len (details)
2257       || !details[vam->current_sw_if_index].present)
2258     {
2259       errmsg ("ip address details arrived but not stored");
2260       errmsg ("ip_dump should be called first");
2261       return;
2262     }
2263
2264   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2265
2266 #define addresses (current_ip_details->addr)
2267
2268   vec_validate_init_empty (addresses, vec_len (addresses),
2269                            empty_ip_address_details);
2270
2271   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2272
2273   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2274   address->prefix_length = mp->prefix_length;
2275 #undef addresses
2276 }
2277
2278 static void vl_api_ip_address_details_t_handler_json
2279   (vl_api_ip_address_details_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t *node = NULL;
2283   struct in6_addr ip6;
2284   struct in_addr ip4;
2285
2286   if (VAT_JSON_ARRAY != vam->json_tree.type)
2287     {
2288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2289       vat_json_init_array (&vam->json_tree);
2290     }
2291   node = vat_json_array_add (&vam->json_tree);
2292
2293   vat_json_init_object (node);
2294   if (vam->is_ipv6)
2295     {
2296       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2297       vat_json_object_add_ip6 (node, "ip", ip6);
2298     }
2299   else
2300     {
2301       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2302       vat_json_object_add_ip4 (node, "ip", ip4);
2303     }
2304   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2305 }
2306
2307 static void
2308 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   static ip_details_t empty_ip_details = { 0 };
2312   ip_details_t *ip = NULL;
2313   u32 sw_if_index = ~0;
2314
2315   sw_if_index = ntohl (mp->sw_if_index);
2316
2317   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2318                            sw_if_index, empty_ip_details);
2319
2320   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2321                          sw_if_index);
2322
2323   ip->present = 1;
2324 }
2325
2326 static void
2327 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330
2331   if (VAT_JSON_ARRAY != vam->json_tree.type)
2332     {
2333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2334       vat_json_init_array (&vam->json_tree);
2335     }
2336   vat_json_array_add_uint (&vam->json_tree,
2337                            clib_net_to_host_u32 (mp->sw_if_index));
2338 }
2339
2340 static void vl_api_map_domain_details_t_handler_json
2341   (vl_api_map_domain_details_t * mp)
2342 {
2343   vat_json_node_t *node = NULL;
2344   vat_main_t *vam = &vat_main;
2345   struct in6_addr ip6;
2346   struct in_addr ip4;
2347
2348   if (VAT_JSON_ARRAY != vam->json_tree.type)
2349     {
2350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2351       vat_json_init_array (&vam->json_tree);
2352     }
2353
2354   node = vat_json_array_add (&vam->json_tree);
2355   vat_json_init_object (node);
2356
2357   vat_json_object_add_uint (node, "domain_index",
2358                             clib_net_to_host_u32 (mp->domain_index));
2359   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2360   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2361   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2362   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2363   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2364   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2365   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2366   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2367   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2368   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2369   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2370   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2371   vat_json_object_add_uint (node, "flags", mp->flags);
2372   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2373   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2374 }
2375
2376 static void vl_api_map_domain_details_t_handler
2377   (vl_api_map_domain_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380
2381   if (mp->is_translation)
2382     {
2383       print (vam->ofp,
2384              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2385              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2386              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2387              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2388              clib_net_to_host_u32 (mp->domain_index));
2389     }
2390   else
2391     {
2392       print (vam->ofp,
2393              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2394              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2395              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2396              format_ip6_address, mp->ip6_src,
2397              clib_net_to_host_u32 (mp->domain_index));
2398     }
2399   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2400          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2401          mp->is_translation ? "map-t" : "");
2402 }
2403
2404 static void vl_api_map_rule_details_t_handler_json
2405   (vl_api_map_rule_details_t * mp)
2406 {
2407   struct in6_addr ip6;
2408   vat_json_node_t *node = NULL;
2409   vat_main_t *vam = &vat_main;
2410
2411   if (VAT_JSON_ARRAY != vam->json_tree.type)
2412     {
2413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2414       vat_json_init_array (&vam->json_tree);
2415     }
2416
2417   node = vat_json_array_add (&vam->json_tree);
2418   vat_json_init_object (node);
2419
2420   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2421   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2422   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2423 }
2424
2425 static void
2426 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2430          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2431 }
2432
2433 static void
2434 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2435 {
2436   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2437           "router_addr %U host_mac %U",
2438           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2439           format_ip4_address, &mp->host_address,
2440           format_ip4_address, &mp->router_address,
2441           format_ethernet_address, mp->host_mac);
2442 }
2443
2444 static void vl_api_dhcp_compl_event_t_handler_json
2445   (vl_api_dhcp_compl_event_t * mp)
2446 {
2447   /* JSON output not supported */
2448 }
2449
2450 static void
2451 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2452                               u32 counter)
2453 {
2454   vat_main_t *vam = &vat_main;
2455   static u64 default_counter = 0;
2456
2457   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2458                            NULL);
2459   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2460                            sw_if_index, default_counter);
2461   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2462 }
2463
2464 static void
2465 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2466                                 interface_counter_t counter)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   static interface_counter_t default_counter = { 0, };
2470
2471   vec_validate_init_empty (vam->combined_interface_counters,
2472                            vnet_counter_type, NULL);
2473   vec_validate_init_empty (vam->combined_interface_counters
2474                            [vnet_counter_type], sw_if_index, default_counter);
2475   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2476 }
2477
2478 static void vl_api_vnet_interface_simple_counters_t_handler
2479   (vl_api_vnet_interface_simple_counters_t * mp)
2480 {
2481   /* not supported */
2482 }
2483
2484 static void vl_api_vnet_interface_combined_counters_t_handler
2485   (vl_api_vnet_interface_combined_counters_t * mp)
2486 {
2487   /* not supported */
2488 }
2489
2490 static void vl_api_vnet_interface_simple_counters_t_handler_json
2491   (vl_api_vnet_interface_simple_counters_t * mp)
2492 {
2493   u64 *v_packets;
2494   u64 packets;
2495   u32 count;
2496   u32 first_sw_if_index;
2497   int i;
2498
2499   count = ntohl (mp->count);
2500   first_sw_if_index = ntohl (mp->first_sw_if_index);
2501
2502   v_packets = (u64 *) & mp->data;
2503   for (i = 0; i < count; i++)
2504     {
2505       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2506       set_simple_interface_counter (mp->vnet_counter_type,
2507                                     first_sw_if_index + i, packets);
2508       v_packets++;
2509     }
2510 }
2511
2512 static void vl_api_vnet_interface_combined_counters_t_handler_json
2513   (vl_api_vnet_interface_combined_counters_t * mp)
2514 {
2515   interface_counter_t counter;
2516   vlib_counter_t *v;
2517   u32 first_sw_if_index;
2518   int i;
2519   u32 count;
2520
2521   count = ntohl (mp->count);
2522   first_sw_if_index = ntohl (mp->first_sw_if_index);
2523
2524   v = (vlib_counter_t *) & mp->data;
2525   for (i = 0; i < count; i++)
2526     {
2527       counter.packets =
2528         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2529       counter.bytes =
2530         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2531       set_combined_interface_counter (mp->vnet_counter_type,
2532                                       first_sw_if_index + i, counter);
2533       v++;
2534     }
2535 }
2536
2537 static u32
2538 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2539 {
2540   vat_main_t *vam = &vat_main;
2541   u32 i;
2542
2543   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2544     {
2545       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2546         {
2547           return i;
2548         }
2549     }
2550   return ~0;
2551 }
2552
2553 static u32
2554 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   u32 i;
2558
2559   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2560     {
2561       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2562         {
2563           return i;
2564         }
2565     }
2566   return ~0;
2567 }
2568
2569 static void vl_api_vnet_ip4_fib_counters_t_handler
2570   (vl_api_vnet_ip4_fib_counters_t * mp)
2571 {
2572   /* not supported */
2573 }
2574
2575 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2576   (vl_api_vnet_ip4_fib_counters_t * mp)
2577 {
2578   vat_main_t *vam = &vat_main;
2579   vl_api_ip4_fib_counter_t *v;
2580   ip4_fib_counter_t *counter;
2581   struct in_addr ip4;
2582   u32 vrf_id;
2583   u32 vrf_index;
2584   u32 count;
2585   int i;
2586
2587   vrf_id = ntohl (mp->vrf_id);
2588   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2589   if (~0 == vrf_index)
2590     {
2591       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2592       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2593       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2594       vec_validate (vam->ip4_fib_counters, vrf_index);
2595       vam->ip4_fib_counters[vrf_index] = NULL;
2596     }
2597
2598   vec_free (vam->ip4_fib_counters[vrf_index]);
2599   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2600   count = ntohl (mp->count);
2601   for (i = 0; i < count; i++)
2602     {
2603       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2604       counter = &vam->ip4_fib_counters[vrf_index][i];
2605       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2606       counter->address = ip4;
2607       counter->address_length = v->address_length;
2608       counter->packets = clib_net_to_host_u64 (v->packets);
2609       counter->bytes = clib_net_to_host_u64 (v->bytes);
2610       v++;
2611     }
2612 }
2613
2614 static void vl_api_vnet_ip4_nbr_counters_t_handler
2615   (vl_api_vnet_ip4_nbr_counters_t * mp)
2616 {
2617   /* not supported */
2618 }
2619
2620 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2621   (vl_api_vnet_ip4_nbr_counters_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vl_api_ip4_nbr_counter_t *v;
2625   ip4_nbr_counter_t *counter;
2626   u32 sw_if_index;
2627   u32 count;
2628   int i;
2629
2630   sw_if_index = ntohl (mp->sw_if_index);
2631   count = ntohl (mp->count);
2632   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2633
2634   if (mp->begin)
2635     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2636
2637   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2638   for (i = 0; i < count; i++)
2639     {
2640       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2641       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2642       counter->address.s_addr = v->address;
2643       counter->packets = clib_net_to_host_u64 (v->packets);
2644       counter->bytes = clib_net_to_host_u64 (v->bytes);
2645       counter->linkt = v->link_type;
2646       v++;
2647     }
2648 }
2649
2650 static void vl_api_vnet_ip6_fib_counters_t_handler
2651   (vl_api_vnet_ip6_fib_counters_t * mp)
2652 {
2653   /* not supported */
2654 }
2655
2656 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2657   (vl_api_vnet_ip6_fib_counters_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vl_api_ip6_fib_counter_t *v;
2661   ip6_fib_counter_t *counter;
2662   struct in6_addr ip6;
2663   u32 vrf_id;
2664   u32 vrf_index;
2665   u32 count;
2666   int i;
2667
2668   vrf_id = ntohl (mp->vrf_id);
2669   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2670   if (~0 == vrf_index)
2671     {
2672       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2673       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2674       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2675       vec_validate (vam->ip6_fib_counters, vrf_index);
2676       vam->ip6_fib_counters[vrf_index] = NULL;
2677     }
2678
2679   vec_free (vam->ip6_fib_counters[vrf_index]);
2680   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2681   count = ntohl (mp->count);
2682   for (i = 0; i < count; i++)
2683     {
2684       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2685       counter = &vam->ip6_fib_counters[vrf_index][i];
2686       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2687       counter->address = ip6;
2688       counter->address_length = v->address_length;
2689       counter->packets = clib_net_to_host_u64 (v->packets);
2690       counter->bytes = clib_net_to_host_u64 (v->bytes);
2691       v++;
2692     }
2693 }
2694
2695 static void vl_api_vnet_ip6_nbr_counters_t_handler
2696   (vl_api_vnet_ip6_nbr_counters_t * mp)
2697 {
2698   /* not supported */
2699 }
2700
2701 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2702   (vl_api_vnet_ip6_nbr_counters_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vl_api_ip6_nbr_counter_t *v;
2706   ip6_nbr_counter_t *counter;
2707   struct in6_addr ip6;
2708   u32 sw_if_index;
2709   u32 count;
2710   int i;
2711
2712   sw_if_index = ntohl (mp->sw_if_index);
2713   count = ntohl (mp->count);
2714   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2715
2716   if (mp->begin)
2717     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2718
2719   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2720   for (i = 0; i < count; i++)
2721     {
2722       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2723       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2724       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2725       counter->address = ip6;
2726       counter->packets = clib_net_to_host_u64 (v->packets);
2727       counter->bytes = clib_net_to_host_u64 (v->bytes);
2728       v++;
2729     }
2730 }
2731
2732 static void vl_api_get_first_msg_id_reply_t_handler
2733   (vl_api_get_first_msg_id_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (vam->async_mode)
2739     {
2740       vam->async_errors += (retval < 0);
2741     }
2742   else
2743     {
2744       vam->retval = retval;
2745       vam->result_ready = 1;
2746     }
2747   if (retval >= 0)
2748     {
2749       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2750     }
2751 }
2752
2753 static void vl_api_get_first_msg_id_reply_t_handler_json
2754   (vl_api_get_first_msg_id_reply_t * mp)
2755 {
2756   vat_main_t *vam = &vat_main;
2757   vat_json_node_t node;
2758
2759   vat_json_init_object (&node);
2760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2761   vat_json_object_add_uint (&node, "first_msg_id",
2762                             (uint) ntohs (mp->first_msg_id));
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static void vl_api_get_node_graph_reply_t_handler
2772   (vl_api_get_node_graph_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   api_main_t *am = &api_main;
2776   i32 retval = ntohl (mp->retval);
2777   u8 *pvt_copy, *reply;
2778   void *oldheap;
2779   vlib_node_t *node;
2780   int i;
2781
2782   if (vam->async_mode)
2783     {
2784       vam->async_errors += (retval < 0);
2785     }
2786   else
2787     {
2788       vam->retval = retval;
2789       vam->result_ready = 1;
2790     }
2791
2792   /* "Should never happen..." */
2793   if (retval != 0)
2794     return;
2795
2796   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2797   pvt_copy = vec_dup (reply);
2798
2799   /* Toss the shared-memory original... */
2800   pthread_mutex_lock (&am->vlib_rp->mutex);
2801   oldheap = svm_push_data_heap (am->vlib_rp);
2802
2803   vec_free (reply);
2804
2805   svm_pop_heap (oldheap);
2806   pthread_mutex_unlock (&am->vlib_rp->mutex);
2807
2808   if (vam->graph_nodes)
2809     {
2810       hash_free (vam->graph_node_index_by_name);
2811
2812       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2813         {
2814           node = vam->graph_nodes[i];
2815           vec_free (node->name);
2816           vec_free (node->next_nodes);
2817           vec_free (node);
2818         }
2819       vec_free (vam->graph_nodes);
2820     }
2821
2822   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2823   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2824   vec_free (pvt_copy);
2825
2826   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2827     {
2828       node = vam->graph_nodes[i];
2829       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2830     }
2831 }
2832
2833 static void vl_api_get_node_graph_reply_t_handler_json
2834   (vl_api_get_node_graph_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   api_main_t *am = &api_main;
2838   void *oldheap;
2839   vat_json_node_t node;
2840   u8 *reply;
2841
2842   /* $$$$ make this real? */
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2846
2847   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2848
2849   /* Toss the shared-memory original... */
2850   pthread_mutex_lock (&am->vlib_rp->mutex);
2851   oldheap = svm_push_data_heap (am->vlib_rp);
2852
2853   vec_free (reply);
2854
2855   svm_pop_heap (oldheap);
2856   pthread_mutex_unlock (&am->vlib_rp->mutex);
2857
2858   vat_json_print (vam->ofp, &node);
2859   vat_json_free (&node);
2860
2861   vam->retval = ntohl (mp->retval);
2862   vam->result_ready = 1;
2863 }
2864
2865 static void
2866 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2867 {
2868   vat_main_t *vam = &vat_main;
2869   u8 *s = 0;
2870
2871   if (mp->local)
2872     {
2873       s = format (s, "%=16d%=16d%=16d",
2874                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2875     }
2876   else
2877     {
2878       s = format (s, "%=16U%=16d%=16d",
2879                   mp->is_ipv6 ? format_ip6_address :
2880                   format_ip4_address,
2881                   mp->ip_address, mp->priority, mp->weight);
2882     }
2883
2884   print (vam->ofp, "%v", s);
2885   vec_free (s);
2886 }
2887
2888 static void
2889 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2890 {
2891   vat_main_t *vam = &vat_main;
2892   vat_json_node_t *node = NULL;
2893   struct in6_addr ip6;
2894   struct in_addr ip4;
2895
2896   if (VAT_JSON_ARRAY != vam->json_tree.type)
2897     {
2898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2899       vat_json_init_array (&vam->json_tree);
2900     }
2901   node = vat_json_array_add (&vam->json_tree);
2902   vat_json_init_object (node);
2903
2904   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2905   vat_json_object_add_uint (node, "priority", mp->priority);
2906   vat_json_object_add_uint (node, "weight", mp->weight);
2907
2908   if (mp->local)
2909     vat_json_object_add_uint (node, "sw_if_index",
2910                               clib_net_to_host_u32 (mp->sw_if_index));
2911   else
2912     {
2913       if (mp->is_ipv6)
2914         {
2915           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2916           vat_json_object_add_ip6 (node, "address", ip6);
2917         }
2918       else
2919         {
2920           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2921           vat_json_object_add_ip4 (node, "address", ip4);
2922         }
2923     }
2924 }
2925
2926 static void
2927 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2928                                           mp)
2929 {
2930   vat_main_t *vam = &vat_main;
2931   u8 *ls_name = 0;
2932
2933   ls_name = format (0, "%s", mp->ls_name);
2934
2935   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2936          ls_name);
2937   vec_free (ls_name);
2938 }
2939
2940 static void
2941   vl_api_one_locator_set_details_t_handler_json
2942   (vl_api_one_locator_set_details_t * mp)
2943 {
2944   vat_main_t *vam = &vat_main;
2945   vat_json_node_t *node = 0;
2946   u8 *ls_name = 0;
2947
2948   ls_name = format (0, "%s", mp->ls_name);
2949   vec_add1 (ls_name, 0);
2950
2951   if (VAT_JSON_ARRAY != vam->json_tree.type)
2952     {
2953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2954       vat_json_init_array (&vam->json_tree);
2955     }
2956   node = vat_json_array_add (&vam->json_tree);
2957
2958   vat_json_init_object (node);
2959   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2960   vat_json_object_add_uint (node, "ls_index",
2961                             clib_net_to_host_u32 (mp->ls_index));
2962   vec_free (ls_name);
2963 }
2964
2965 typedef struct
2966 {
2967   u32 spi;
2968   u8 si;
2969 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2970
2971 uword
2972 unformat_nsh_address (unformat_input_t * input, va_list * args)
2973 {
2974   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2975   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2976 }
2977
2978 u8 *
2979 format_nsh_address_vat (u8 * s, va_list * args)
2980 {
2981   nsh_t *a = va_arg (*args, nsh_t *);
2982   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2983 }
2984
2985 static u8 *
2986 format_lisp_flat_eid (u8 * s, va_list * args)
2987 {
2988   u32 type = va_arg (*args, u32);
2989   u8 *eid = va_arg (*args, u8 *);
2990   u32 eid_len = va_arg (*args, u32);
2991
2992   switch (type)
2993     {
2994     case 0:
2995       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2996     case 1:
2997       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2998     case 2:
2999       return format (s, "%U", format_ethernet_address, eid);
3000     case 3:
3001       return format (s, "%U", format_nsh_address_vat, eid);
3002     }
3003   return 0;
3004 }
3005
3006 static u8 *
3007 format_lisp_eid_vat (u8 * s, va_list * args)
3008 {
3009   u32 type = va_arg (*args, u32);
3010   u8 *eid = va_arg (*args, u8 *);
3011   u32 eid_len = va_arg (*args, u32);
3012   u8 *seid = va_arg (*args, u8 *);
3013   u32 seid_len = va_arg (*args, u32);
3014   u32 is_src_dst = va_arg (*args, u32);
3015
3016   if (is_src_dst)
3017     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3018
3019   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3020
3021   return s;
3022 }
3023
3024 static void
3025 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u8 *s = 0, *eid = 0;
3029
3030   if (~0 == mp->locator_set_index)
3031     s = format (0, "action: %d", mp->action);
3032   else
3033     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3034
3035   eid = format (0, "%U", format_lisp_eid_vat,
3036                 mp->eid_type,
3037                 mp->eid,
3038                 mp->eid_prefix_len,
3039                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3040   vec_add1 (eid, 0);
3041
3042   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3043          clib_net_to_host_u32 (mp->vni),
3044          eid,
3045          mp->is_local ? "local" : "remote",
3046          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3047          clib_net_to_host_u16 (mp->key_id), mp->key);
3048
3049   vec_free (s);
3050   vec_free (eid);
3051 }
3052
3053 static void
3054 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3055                                              * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058   vat_json_node_t *node = 0;
3059   u8 *eid = 0;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   if (~0 == mp->locator_set_index)
3070     vat_json_object_add_uint (node, "action", mp->action);
3071   else
3072     vat_json_object_add_uint (node, "locator_set_index",
3073                               clib_net_to_host_u32 (mp->locator_set_index));
3074
3075   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3076   if (mp->eid_type == 3)
3077     {
3078       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3079       vat_json_init_object (nsh_json);
3080       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3081       vat_json_object_add_uint (nsh_json, "spi",
3082                                 clib_net_to_host_u32 (nsh->spi));
3083       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3084     }
3085   else
3086     {
3087       eid = format (0, "%U", format_lisp_eid_vat,
3088                     mp->eid_type,
3089                     mp->eid,
3090                     mp->eid_prefix_len,
3091                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3092       vec_add1 (eid, 0);
3093       vat_json_object_add_string_copy (node, "eid", eid);
3094       vec_free (eid);
3095     }
3096   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3097   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3098   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3099
3100   if (mp->key_id)
3101     {
3102       vat_json_object_add_uint (node, "key_id",
3103                                 clib_net_to_host_u16 (mp->key_id));
3104       vat_json_object_add_string_copy (node, "key", mp->key);
3105     }
3106 }
3107
3108 static void
3109 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *seid = 0, *deid = 0;
3113   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3114
3115   deid = format (0, "%U", format_lisp_eid_vat,
3116                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3117
3118   seid = format (0, "%U", format_lisp_eid_vat,
3119                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3120
3121   vec_add1 (deid, 0);
3122   vec_add1 (seid, 0);
3123
3124   if (mp->is_ip4)
3125     format_ip_address_fcn = format_ip4_address;
3126   else
3127     format_ip_address_fcn = format_ip6_address;
3128
3129
3130   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3131          clib_net_to_host_u32 (mp->vni),
3132          seid, deid,
3133          format_ip_address_fcn, mp->lloc,
3134          format_ip_address_fcn, mp->rloc,
3135          clib_net_to_host_u32 (mp->pkt_count),
3136          clib_net_to_host_u32 (mp->bytes));
3137
3138   vec_free (deid);
3139   vec_free (seid);
3140 }
3141
3142 static void
3143 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3144 {
3145   struct in6_addr ip6;
3146   struct in_addr ip4;
3147   vat_main_t *vam = &vat_main;
3148   vat_json_node_t *node = 0;
3149   u8 *deid = 0, *seid = 0;
3150
3151   if (VAT_JSON_ARRAY != vam->json_tree.type)
3152     {
3153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3154       vat_json_init_array (&vam->json_tree);
3155     }
3156   node = vat_json_array_add (&vam->json_tree);
3157
3158   vat_json_init_object (node);
3159   deid = format (0, "%U", format_lisp_eid_vat,
3160                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3161
3162   seid = format (0, "%U", format_lisp_eid_vat,
3163                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3164
3165   vec_add1 (deid, 0);
3166   vec_add1 (seid, 0);
3167
3168   vat_json_object_add_string_copy (node, "seid", seid);
3169   vat_json_object_add_string_copy (node, "deid", deid);
3170   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3171
3172   if (mp->is_ip4)
3173     {
3174       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3175       vat_json_object_add_ip4 (node, "lloc", ip4);
3176       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3177       vat_json_object_add_ip4 (node, "rloc", ip4);
3178     }
3179   else
3180     {
3181       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3182       vat_json_object_add_ip6 (node, "lloc", ip6);
3183       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3184       vat_json_object_add_ip6 (node, "rloc", ip6);
3185     }
3186   vat_json_object_add_uint (node, "pkt_count",
3187                             clib_net_to_host_u32 (mp->pkt_count));
3188   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3189
3190   vec_free (deid);
3191   vec_free (seid);
3192 }
3193
3194 static void
3195   vl_api_one_eid_table_map_details_t_handler
3196   (vl_api_one_eid_table_map_details_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199
3200   u8 *line = format (0, "%=10d%=10d",
3201                      clib_net_to_host_u32 (mp->vni),
3202                      clib_net_to_host_u32 (mp->dp_table));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_map_details_t_handler_json
3209   (vl_api_one_eid_table_map_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node = NULL;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220   vat_json_init_object (node);
3221   vat_json_object_add_uint (node, "dp_table",
3222                             clib_net_to_host_u32 (mp->dp_table));
3223   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3224 }
3225
3226 static void
3227   vl_api_one_eid_table_vni_details_t_handler
3228   (vl_api_one_eid_table_vni_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3233   print (vam->ofp, "%v", line);
3234   vec_free (line);
3235 }
3236
3237 static void
3238   vl_api_one_eid_table_vni_details_t_handler_json
3239   (vl_api_one_eid_table_vni_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   vat_json_node_t *node = NULL;
3243
3244   if (VAT_JSON_ARRAY != vam->json_tree.type)
3245     {
3246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3247       vat_json_init_array (&vam->json_tree);
3248     }
3249   node = vat_json_array_add (&vam->json_tree);
3250   vat_json_init_object (node);
3251   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3252 }
3253
3254 static void
3255   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3256   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   int retval = clib_net_to_host_u32 (mp->retval);
3260
3261   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3262   print (vam->ofp, "fallback threshold value: %d", mp->value);
3263
3264   vam->retval = retval;
3265   vam->result_ready = 1;
3266 }
3267
3268 static void
3269   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3270   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3271 {
3272   vat_main_t *vam = &vat_main;
3273   vat_json_node_t _node, *node = &_node;
3274   int retval = clib_net_to_host_u32 (mp->retval);
3275
3276   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3277   vat_json_init_object (node);
3278   vat_json_object_add_uint (node, "value", mp->value);
3279
3280   vat_json_print (vam->ofp, node);
3281   vat_json_free (node);
3282
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_show_one_map_register_state_reply_t_handler
3289   (vl_api_show_one_map_register_state_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3295
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_map_register_state_reply_t_handler_json
3302   (vl_api_show_one_map_register_state_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3309
3310   vat_json_init_object (node);
3311   vat_json_object_add_string_copy (node, "state", s);
3312
3313   vat_json_print (vam->ofp, node);
3314   vat_json_free (node);
3315
3316   vam->retval = retval;
3317   vam->result_ready = 1;
3318   vec_free (s);
3319 }
3320
3321 static void
3322   vl_api_show_one_rloc_probe_state_reply_t_handler
3323   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   int retval = clib_net_to_host_u32 (mp->retval);
3327
3328   if (retval)
3329     goto end;
3330
3331   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3332 end:
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3339   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3346   vat_json_init_object (node);
3347   vat_json_object_add_string_copy (node, "state", s);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354   vec_free (s);
3355 }
3356
3357 static void
3358   vl_api_show_one_stats_enable_disable_reply_t_handler
3359   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3360 {
3361   vat_main_t *vam = &vat_main;
3362   int retval = clib_net_to_host_u32 (mp->retval);
3363
3364   if (retval)
3365     goto end;
3366
3367   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3368 end:
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371 }
3372
3373 static void
3374   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3375   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t _node, *node = &_node;
3379   int retval = clib_net_to_host_u32 (mp->retval);
3380
3381   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3382   vat_json_init_object (node);
3383   vat_json_object_add_string_copy (node, "state", s);
3384
3385   vat_json_print (vam->ofp, node);
3386   vat_json_free (node);
3387
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390   vec_free (s);
3391 }
3392
3393 static void
3394 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3395 {
3396   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3397   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3398   e->vni = clib_net_to_host_u32 (e->vni);
3399 }
3400
3401 static void
3402   gpe_fwd_entries_get_reply_t_net_to_host
3403   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3404 {
3405   u32 i;
3406
3407   mp->count = clib_net_to_host_u32 (mp->count);
3408   for (i = 0; i < mp->count; i++)
3409     {
3410       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3411     }
3412 }
3413
3414 static u8 *
3415 format_gpe_encap_mode (u8 * s, va_list * args)
3416 {
3417   u32 mode = va_arg (*args, u32);
3418
3419   switch (mode)
3420     {
3421     case 0:
3422       return format (s, "lisp");
3423     case 1:
3424       return format (s, "vxlan");
3425     }
3426   return 0;
3427 }
3428
3429 static void
3430   vl_api_gpe_get_encap_mode_reply_t_handler
3431   (vl_api_gpe_get_encap_mode_reply_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3436   vam->retval = ntohl (mp->retval);
3437   vam->result_ready = 1;
3438 }
3439
3440 static void
3441   vl_api_gpe_get_encap_mode_reply_t_handler_json
3442   (vl_api_gpe_get_encap_mode_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   vat_json_node_t node;
3446
3447   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3448   vec_add1 (encap_mode, 0);
3449
3450   vat_json_init_object (&node);
3451   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3452
3453   vec_free (encap_mode);
3454   vat_json_print (vam->ofp, &node);
3455   vat_json_free (&node);
3456
3457   vam->retval = ntohl (mp->retval);
3458   vam->result_ready = 1;
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entry_path_details_t_handler
3463   (vl_api_gpe_fwd_entry_path_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3467
3468   if (mp->lcl_loc.is_ip4)
3469     format_ip_address_fcn = format_ip4_address;
3470   else
3471     format_ip_address_fcn = format_ip6_address;
3472
3473   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3474          format_ip_address_fcn, &mp->lcl_loc,
3475          format_ip_address_fcn, &mp->rmt_loc);
3476 }
3477
3478 static void
3479 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3480 {
3481   struct in6_addr ip6;
3482   struct in_addr ip4;
3483
3484   if (loc->is_ip4)
3485     {
3486       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3487       vat_json_object_add_ip4 (n, "address", ip4);
3488     }
3489   else
3490     {
3491       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3492       vat_json_object_add_ip6 (n, "address", ip6);
3493     }
3494   vat_json_object_add_uint (n, "weight", loc->weight);
3495 }
3496
3497 static void
3498   vl_api_gpe_fwd_entry_path_details_t_handler_json
3499   (vl_api_gpe_fwd_entry_path_details_t * mp)
3500 {
3501   vat_main_t *vam = &vat_main;
3502   vat_json_node_t *node = NULL;
3503   vat_json_node_t *loc_node;
3504
3505   if (VAT_JSON_ARRAY != vam->json_tree.type)
3506     {
3507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3508       vat_json_init_array (&vam->json_tree);
3509     }
3510   node = vat_json_array_add (&vam->json_tree);
3511   vat_json_init_object (node);
3512
3513   loc_node = vat_json_object_add (node, "local_locator");
3514   vat_json_init_object (loc_node);
3515   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3516
3517   loc_node = vat_json_object_add (node, "remote_locator");
3518   vat_json_init_object (loc_node);
3519   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3520 }
3521
3522 static void
3523   vl_api_gpe_fwd_entries_get_reply_t_handler
3524   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   u32 i;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_fwd_entry_t *e;
3530
3531   if (retval)
3532     goto end;
3533
3534   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3535
3536   for (i = 0; i < mp->count; i++)
3537     {
3538       e = &mp->entries[i];
3539       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3540              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3541              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3542     }
3543
3544 end:
3545   vam->retval = retval;
3546   vam->result_ready = 1;
3547 }
3548
3549 static void
3550   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3551   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3552 {
3553   u8 *s = 0;
3554   vat_main_t *vam = &vat_main;
3555   vat_json_node_t *e = 0, root;
3556   u32 i;
3557   int retval = clib_net_to_host_u32 (mp->retval);
3558   vl_api_gpe_fwd_entry_t *fwd;
3559
3560   if (retval)
3561     goto end;
3562
3563   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3564   vat_json_init_array (&root);
3565
3566   for (i = 0; i < mp->count; i++)
3567     {
3568       e = vat_json_array_add (&root);
3569       fwd = &mp->entries[i];
3570
3571       vat_json_init_object (e);
3572       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3573       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3574       vat_json_object_add_int (e, "vni", fwd->vni);
3575       vat_json_object_add_int (e, "action", fwd->action);
3576
3577       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3578                   fwd->leid_prefix_len);
3579       vec_add1 (s, 0);
3580       vat_json_object_add_string_copy (e, "leid", s);
3581       vec_free (s);
3582
3583       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3584                   fwd->reid_prefix_len);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "reid", s);
3587       vec_free (s);
3588     }
3589
3590   vat_json_print (vam->ofp, &root);
3591   vat_json_free (&root);
3592
3593 end:
3594   vam->retval = retval;
3595   vam->result_ready = 1;
3596 }
3597
3598 static void
3599   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3600   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3601 {
3602   vat_main_t *vam = &vat_main;
3603   u32 i, n;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605   vl_api_gpe_native_fwd_rpath_t *r;
3606
3607   if (retval)
3608     goto end;
3609
3610   n = clib_net_to_host_u32 (mp->count);
3611
3612   for (i = 0; i < n; i++)
3613     {
3614       r = &mp->entries[i];
3615       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3616              clib_net_to_host_u32 (r->fib_index),
3617              clib_net_to_host_u32 (r->nh_sw_if_index),
3618              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3619     }
3620
3621 end:
3622   vam->retval = retval;
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3628   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t root, *e;
3632   u32 i, n;
3633   int retval = clib_net_to_host_u32 (mp->retval);
3634   vl_api_gpe_native_fwd_rpath_t *r;
3635   u8 *s;
3636
3637   if (retval)
3638     goto end;
3639
3640   n = clib_net_to_host_u32 (mp->count);
3641   vat_json_init_array (&root);
3642
3643   for (i = 0; i < n; i++)
3644     {
3645       e = vat_json_array_add (&root);
3646       vat_json_init_object (e);
3647       r = &mp->entries[i];
3648       s =
3649         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3650                 r->nh_addr);
3651       vec_add1 (s, 0);
3652       vat_json_object_add_string_copy (e, "ip4", s);
3653       vec_free (s);
3654
3655       vat_json_object_add_uint (e, "fib_index",
3656                                 clib_net_to_host_u32 (r->fib_index));
3657       vat_json_object_add_uint (e, "nh_sw_if_index",
3658                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3659     }
3660
3661   vat_json_print (vam->ofp, &root);
3662   vat_json_free (&root);
3663
3664 end:
3665   vam->retval = retval;
3666   vam->result_ready = 1;
3667 }
3668
3669 static void
3670   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3671   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3672 {
3673   vat_main_t *vam = &vat_main;
3674   u32 i, n;
3675   int retval = clib_net_to_host_u32 (mp->retval);
3676
3677   if (retval)
3678     goto end;
3679
3680   n = clib_net_to_host_u32 (mp->count);
3681
3682   for (i = 0; i < n; i++)
3683     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3692   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   vat_json_node_t root;
3696   u32 i, n;
3697   int retval = clib_net_to_host_u32 (mp->retval);
3698
3699   if (retval)
3700     goto end;
3701
3702   n = clib_net_to_host_u32 (mp->count);
3703   vat_json_init_array (&root);
3704
3705   for (i = 0; i < n; i++)
3706     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3707
3708   vat_json_print (vam->ofp, &root);
3709   vat_json_free (&root);
3710
3711 end:
3712   vam->retval = retval;
3713   vam->result_ready = 1;
3714 }
3715
3716 static void
3717   vl_api_one_ndp_entries_get_reply_t_handler
3718   (vl_api_one_ndp_entries_get_reply_t * mp)
3719 {
3720   vat_main_t *vam = &vat_main;
3721   u32 i, n;
3722   int retval = clib_net_to_host_u32 (mp->retval);
3723
3724   if (retval)
3725     goto end;
3726
3727   n = clib_net_to_host_u32 (mp->count);
3728
3729   for (i = 0; i < n; i++)
3730     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3731            format_ethernet_address, mp->entries[i].mac);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_one_ndp_entries_get_reply_t_handler_json
3740   (vl_api_one_ndp_entries_get_reply_t * mp)
3741 {
3742   u8 *s = 0;
3743   vat_main_t *vam = &vat_main;
3744   vat_json_node_t *e = 0, root;
3745   u32 i, n;
3746   int retval = clib_net_to_host_u32 (mp->retval);
3747   vl_api_one_ndp_entry_t *arp_entry;
3748
3749   if (retval)
3750     goto end;
3751
3752   n = clib_net_to_host_u32 (mp->count);
3753   vat_json_init_array (&root);
3754
3755   for (i = 0; i < n; i++)
3756     {
3757       e = vat_json_array_add (&root);
3758       arp_entry = &mp->entries[i];
3759
3760       vat_json_init_object (e);
3761       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3762       vec_add1 (s, 0);
3763
3764       vat_json_object_add_string_copy (e, "mac", s);
3765       vec_free (s);
3766
3767       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3768       vec_add1 (s, 0);
3769       vat_json_object_add_string_copy (e, "ip6", s);
3770       vec_free (s);
3771     }
3772
3773   vat_json_print (vam->ofp, &root);
3774   vat_json_free (&root);
3775
3776 end:
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_one_l2_arp_entries_get_reply_t_handler
3783   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   u32 i, n;
3787   int retval = clib_net_to_host_u32 (mp->retval);
3788
3789   if (retval)
3790     goto end;
3791
3792   n = clib_net_to_host_u32 (mp->count);
3793
3794   for (i = 0; i < n; i++)
3795     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3796            format_ethernet_address, mp->entries[i].mac);
3797
3798 end:
3799   vam->retval = retval;
3800   vam->result_ready = 1;
3801 }
3802
3803 static void
3804   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3805   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3806 {
3807   u8 *s = 0;
3808   vat_main_t *vam = &vat_main;
3809   vat_json_node_t *e = 0, root;
3810   u32 i, n;
3811   int retval = clib_net_to_host_u32 (mp->retval);
3812   vl_api_one_l2_arp_entry_t *arp_entry;
3813
3814   if (retval)
3815     goto end;
3816
3817   n = clib_net_to_host_u32 (mp->count);
3818   vat_json_init_array (&root);
3819
3820   for (i = 0; i < n; i++)
3821     {
3822       e = vat_json_array_add (&root);
3823       arp_entry = &mp->entries[i];
3824
3825       vat_json_init_object (e);
3826       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3827       vec_add1 (s, 0);
3828
3829       vat_json_object_add_string_copy (e, "mac", s);
3830       vec_free (s);
3831
3832       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3833       vec_add1 (s, 0);
3834       vat_json_object_add_string_copy (e, "ip4", s);
3835       vec_free (s);
3836     }
3837
3838   vat_json_print (vam->ofp, &root);
3839   vat_json_free (&root);
3840
3841 end:
3842   vam->retval = retval;
3843   vam->result_ready = 1;
3844 }
3845
3846 static void
3847 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   u32 i, n;
3851   int retval = clib_net_to_host_u32 (mp->retval);
3852
3853   if (retval)
3854     goto end;
3855
3856   n = clib_net_to_host_u32 (mp->count);
3857
3858   for (i = 0; i < n; i++)
3859     {
3860       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3861     }
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_ndp_bd_get_reply_t_handler_json
3870   (vl_api_one_ndp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   vat_json_node_t root;
3874   u32 i, n;
3875   int retval = clib_net_to_host_u32 (mp->retval);
3876
3877   if (retval)
3878     goto end;
3879
3880   n = clib_net_to_host_u32 (mp->count);
3881   vat_json_init_array (&root);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       vat_json_array_add_uint (&root,
3886                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3887     }
3888
3889   vat_json_print (vam->ofp, &root);
3890   vat_json_free (&root);
3891
3892 end:
3893   vam->retval = retval;
3894   vam->result_ready = 1;
3895 }
3896
3897 static void
3898   vl_api_one_l2_arp_bd_get_reply_t_handler
3899   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3900 {
3901   vat_main_t *vam = &vat_main;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904
3905   if (retval)
3906     goto end;
3907
3908   n = clib_net_to_host_u32 (mp->count);
3909
3910   for (i = 0; i < n; i++)
3911     {
3912       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3913     }
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3922   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   vat_json_node_t root;
3926   u32 i, n;
3927   int retval = clib_net_to_host_u32 (mp->retval);
3928
3929   if (retval)
3930     goto end;
3931
3932   n = clib_net_to_host_u32 (mp->count);
3933   vat_json_init_array (&root);
3934
3935   for (i = 0; i < n; i++)
3936     {
3937       vat_json_array_add_uint (&root,
3938                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3939     }
3940
3941   vat_json_print (vam->ofp, &root);
3942   vat_json_free (&root);
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_one_adjacencies_get_reply_t_handler
3951   (vl_api_one_adjacencies_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956   vl_api_one_adjacency_t *a;
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962
3963   for (i = 0; i < n; i++)
3964     {
3965       a = &mp->adjacencies[i];
3966       print (vam->ofp, "%U %40U",
3967              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3968              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3969     }
3970
3971 end:
3972   vam->retval = retval;
3973   vam->result_ready = 1;
3974 }
3975
3976 static void
3977   vl_api_one_adjacencies_get_reply_t_handler_json
3978   (vl_api_one_adjacencies_get_reply_t * mp)
3979 {
3980   u8 *s = 0;
3981   vat_main_t *vam = &vat_main;
3982   vat_json_node_t *e = 0, root;
3983   u32 i, n;
3984   int retval = clib_net_to_host_u32 (mp->retval);
3985   vl_api_one_adjacency_t *a;
3986
3987   if (retval)
3988     goto end;
3989
3990   n = clib_net_to_host_u32 (mp->count);
3991   vat_json_init_array (&root);
3992
3993   for (i = 0; i < n; i++)
3994     {
3995       e = vat_json_array_add (&root);
3996       a = &mp->adjacencies[i];
3997
3998       vat_json_init_object (e);
3999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4000                   a->leid_prefix_len);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "leid", s);
4003       vec_free (s);
4004
4005       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4006                   a->reid_prefix_len);
4007       vec_add1 (s, 0);
4008       vat_json_object_add_string_copy (e, "reid", s);
4009       vec_free (s);
4010     }
4011
4012   vat_json_print (vam->ofp, &root);
4013   vat_json_free (&root);
4014
4015 end:
4016   vam->retval = retval;
4017   vam->result_ready = 1;
4018 }
4019
4020 static void
4021 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4022 {
4023   vat_main_t *vam = &vat_main;
4024
4025   print (vam->ofp, "%=20U",
4026          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4027          mp->ip_address);
4028 }
4029
4030 static void
4031   vl_api_one_map_server_details_t_handler_json
4032   (vl_api_one_map_server_details_t * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035   vat_json_node_t *node = NULL;
4036   struct in6_addr ip6;
4037   struct in_addr ip4;
4038
4039   if (VAT_JSON_ARRAY != vam->json_tree.type)
4040     {
4041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4042       vat_json_init_array (&vam->json_tree);
4043     }
4044   node = vat_json_array_add (&vam->json_tree);
4045
4046   vat_json_init_object (node);
4047   if (mp->is_ipv6)
4048     {
4049       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4050       vat_json_object_add_ip6 (node, "map-server", ip6);
4051     }
4052   else
4053     {
4054       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4055       vat_json_object_add_ip4 (node, "map-server", ip4);
4056     }
4057 }
4058
4059 static void
4060 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4061                                            * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064
4065   print (vam->ofp, "%=20U",
4066          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4067          mp->ip_address);
4068 }
4069
4070 static void
4071   vl_api_one_map_resolver_details_t_handler_json
4072   (vl_api_one_map_resolver_details_t * mp)
4073 {
4074   vat_main_t *vam = &vat_main;
4075   vat_json_node_t *node = NULL;
4076   struct in6_addr ip6;
4077   struct in_addr ip4;
4078
4079   if (VAT_JSON_ARRAY != vam->json_tree.type)
4080     {
4081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4082       vat_json_init_array (&vam->json_tree);
4083     }
4084   node = vat_json_array_add (&vam->json_tree);
4085
4086   vat_json_init_object (node);
4087   if (mp->is_ipv6)
4088     {
4089       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4090       vat_json_object_add_ip6 (node, "map resolver", ip6);
4091     }
4092   else
4093     {
4094       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4095       vat_json_object_add_ip4 (node, "map resolver", ip4);
4096     }
4097 }
4098
4099 static void
4100 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       print (vam->ofp, "feature: %s\ngpe: %s",
4108              mp->feature_status ? "enabled" : "disabled",
4109              mp->gpe_status ? "enabled" : "disabled");
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_status_reply_t_handler_json
4118   (vl_api_show_one_status_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *gpe_status = NULL;
4123   u8 *feature_status = NULL;
4124
4125   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4126   feature_status = format (0, "%s",
4127                            mp->feature_status ? "enabled" : "disabled");
4128   vec_add1 (gpe_status, 0);
4129   vec_add1 (feature_status, 0);
4130
4131   vat_json_init_object (&node);
4132   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4133   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4134
4135   vec_free (gpe_status);
4136   vec_free (feature_status);
4137
4138   vat_json_print (vam->ofp, &node);
4139   vat_json_free (&node);
4140
4141   vam->retval = ntohl (mp->retval);
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4147   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   i32 retval = ntohl (mp->retval);
4151
4152   if (retval >= 0)
4153     {
4154       print (vam->ofp, "%=20s", mp->locator_set_name);
4155     }
4156
4157   vam->retval = retval;
4158   vam->result_ready = 1;
4159 }
4160
4161 static void
4162   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4163   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4164 {
4165   vat_main_t *vam = &vat_main;
4166   vat_json_node_t *node = NULL;
4167
4168   if (VAT_JSON_ARRAY != vam->json_tree.type)
4169     {
4170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4171       vat_json_init_array (&vam->json_tree);
4172     }
4173   node = vat_json_array_add (&vam->json_tree);
4174
4175   vat_json_init_object (node);
4176   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4177
4178   vat_json_print (vam->ofp, node);
4179   vat_json_free (node);
4180
4181   vam->retval = ntohl (mp->retval);
4182   vam->result_ready = 1;
4183 }
4184
4185 static u8 *
4186 format_lisp_map_request_mode (u8 * s, va_list * args)
4187 {
4188   u32 mode = va_arg (*args, u32);
4189
4190   switch (mode)
4191     {
4192     case 0:
4193       return format (0, "dst-only");
4194     case 1:
4195       return format (0, "src-dst");
4196     }
4197   return 0;
4198 }
4199
4200 static void
4201   vl_api_show_one_map_request_mode_reply_t_handler
4202   (vl_api_show_one_map_request_mode_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   i32 retval = ntohl (mp->retval);
4206
4207   if (0 <= retval)
4208     {
4209       u32 mode = mp->mode;
4210       print (vam->ofp, "map_request_mode: %U",
4211              format_lisp_map_request_mode, mode);
4212     }
4213
4214   vam->retval = retval;
4215   vam->result_ready = 1;
4216 }
4217
4218 static void
4219   vl_api_show_one_map_request_mode_reply_t_handler_json
4220   (vl_api_show_one_map_request_mode_reply_t * mp)
4221 {
4222   vat_main_t *vam = &vat_main;
4223   vat_json_node_t node;
4224   u8 *s = 0;
4225   u32 mode;
4226
4227   mode = mp->mode;
4228   s = format (0, "%U", format_lisp_map_request_mode, mode);
4229   vec_add1 (s, 0);
4230
4231   vat_json_init_object (&node);
4232   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4233   vat_json_print (vam->ofp, &node);
4234   vat_json_free (&node);
4235
4236   vec_free (s);
4237   vam->retval = ntohl (mp->retval);
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_show_one_use_petr_reply_t_handler
4243   (vl_api_show_one_use_petr_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   i32 retval = ntohl (mp->retval);
4247
4248   if (0 <= retval)
4249     {
4250       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4251       if (mp->status)
4252         {
4253           print (vam->ofp, "Proxy-ETR address; %U",
4254                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4255                  mp->address);
4256         }
4257     }
4258
4259   vam->retval = retval;
4260   vam->result_ready = 1;
4261 }
4262
4263 static void
4264   vl_api_show_one_use_petr_reply_t_handler_json
4265   (vl_api_show_one_use_petr_reply_t * mp)
4266 {
4267   vat_main_t *vam = &vat_main;
4268   vat_json_node_t node;
4269   u8 *status = 0;
4270   struct in_addr ip4;
4271   struct in6_addr ip6;
4272
4273   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4274   vec_add1 (status, 0);
4275
4276   vat_json_init_object (&node);
4277   vat_json_object_add_string_copy (&node, "status", status);
4278   if (mp->status)
4279     {
4280       if (mp->is_ip4)
4281         {
4282           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4283           vat_json_object_add_ip6 (&node, "address", ip6);
4284         }
4285       else
4286         {
4287           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4288           vat_json_object_add_ip4 (&node, "address", ip4);
4289         }
4290     }
4291
4292   vec_free (status);
4293
4294   vat_json_print (vam->ofp, &node);
4295   vat_json_free (&node);
4296
4297   vam->retval = ntohl (mp->retval);
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_show_one_nsh_mapping_reply_t_handler
4303   (vl_api_show_one_nsh_mapping_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   i32 retval = ntohl (mp->retval);
4307
4308   if (0 <= retval)
4309     {
4310       print (vam->ofp, "%-20s%-16s",
4311              mp->is_set ? "set" : "not-set",
4312              mp->is_set ? (char *) mp->locator_set_name : "");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_nsh_mapping_reply_t_handler_json
4321   (vl_api_show_one_nsh_mapping_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_set ? "yes" : "no");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "is_set", status);
4332   if (mp->is_set)
4333     {
4334       vat_json_object_add_string_copy (&node, "locator_set",
4335                                        mp->locator_set_name);
4336     }
4337
4338   vec_free (status);
4339
4340   vat_json_print (vam->ofp, &node);
4341   vat_json_free (&node);
4342
4343   vam->retval = ntohl (mp->retval);
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_show_one_map_register_ttl_reply_t_handler
4349   (vl_api_show_one_map_register_ttl_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   i32 retval = ntohl (mp->retval);
4353
4354   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "ttl: %u", mp->ttl);
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_show_one_map_register_ttl_reply_t_handler_json
4367   (vl_api_show_one_map_register_ttl_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371
4372   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4373   vat_json_init_object (&node);
4374   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   if (0 <= retval)
4390     {
4391       print (vam->ofp, "%-20s%-16s",
4392              mp->status ? "enabled" : "disabled",
4393              mp->status ? (char *) mp->locator_set_name : "");
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406
4407   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "status", status);
4412   if (mp->status)
4413     {
4414       vat_json_object_add_string_copy (&node, "locator_set",
4415                                        mp->locator_set_name);
4416     }
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static u8 *
4428 format_policer_type (u8 * s, va_list * va)
4429 {
4430   u32 i = va_arg (*va, u32);
4431
4432   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4433     s = format (s, "1r2c");
4434   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4435     s = format (s, "1r3c");
4436   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4437     s = format (s, "2r3c-2698");
4438   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4439     s = format (s, "2r3c-4115");
4440   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4441     s = format (s, "2r3c-mef5cf1");
4442   else
4443     s = format (s, "ILLEGAL");
4444   return s;
4445 }
4446
4447 static u8 *
4448 format_policer_rate_type (u8 * s, va_list * va)
4449 {
4450   u32 i = va_arg (*va, u32);
4451
4452   if (i == SSE2_QOS_RATE_KBPS)
4453     s = format (s, "kbps");
4454   else if (i == SSE2_QOS_RATE_PPS)
4455     s = format (s, "pps");
4456   else
4457     s = format (s, "ILLEGAL");
4458   return s;
4459 }
4460
4461 static u8 *
4462 format_policer_round_type (u8 * s, va_list * va)
4463 {
4464   u32 i = va_arg (*va, u32);
4465
4466   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4467     s = format (s, "closest");
4468   else if (i == SSE2_QOS_ROUND_TO_UP)
4469     s = format (s, "up");
4470   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4471     s = format (s, "down");
4472   else
4473     s = format (s, "ILLEGAL");
4474   return s;
4475 }
4476
4477 static u8 *
4478 format_policer_action_type (u8 * s, va_list * va)
4479 {
4480   u32 i = va_arg (*va, u32);
4481
4482   if (i == SSE2_QOS_ACTION_DROP)
4483     s = format (s, "drop");
4484   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4485     s = format (s, "transmit");
4486   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4487     s = format (s, "mark-and-transmit");
4488   else
4489     s = format (s, "ILLEGAL");
4490   return s;
4491 }
4492
4493 static u8 *
4494 format_dscp (u8 * s, va_list * va)
4495 {
4496   u32 i = va_arg (*va, u32);
4497   char *t = 0;
4498
4499   switch (i)
4500     {
4501 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4502       foreach_vnet_dscp
4503 #undef _
4504     default:
4505       return format (s, "ILLEGAL");
4506     }
4507   s = format (s, "%s", t);
4508   return s;
4509 }
4510
4511 static void
4512 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4516
4517   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4518     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4519   else
4520     conform_dscp_str = format (0, "");
4521
4522   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4523     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4524   else
4525     exceed_dscp_str = format (0, "");
4526
4527   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4528     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4529   else
4530     violate_dscp_str = format (0, "");
4531
4532   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4533          "rate type %U, round type %U, %s rate, %s color-aware, "
4534          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4535          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4536          "conform action %U%s, exceed action %U%s, violate action %U%s",
4537          mp->name,
4538          format_policer_type, mp->type,
4539          ntohl (mp->cir),
4540          ntohl (mp->eir),
4541          clib_net_to_host_u64 (mp->cb),
4542          clib_net_to_host_u64 (mp->eb),
4543          format_policer_rate_type, mp->rate_type,
4544          format_policer_round_type, mp->round_type,
4545          mp->single_rate ? "single" : "dual",
4546          mp->color_aware ? "is" : "not",
4547          ntohl (mp->cir_tokens_per_period),
4548          ntohl (mp->pir_tokens_per_period),
4549          ntohl (mp->scale),
4550          ntohl (mp->current_limit),
4551          ntohl (mp->current_bucket),
4552          ntohl (mp->extended_limit),
4553          ntohl (mp->extended_bucket),
4554          clib_net_to_host_u64 (mp->last_update_time),
4555          format_policer_action_type, mp->conform_action_type,
4556          conform_dscp_str,
4557          format_policer_action_type, mp->exceed_action_type,
4558          exceed_dscp_str,
4559          format_policer_action_type, mp->violate_action_type,
4560          violate_dscp_str);
4561
4562   vec_free (conform_dscp_str);
4563   vec_free (exceed_dscp_str);
4564   vec_free (violate_dscp_str);
4565 }
4566
4567 static void vl_api_policer_details_t_handler_json
4568   (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t *node;
4572   u8 *rate_type_str, *round_type_str, *type_str;
4573   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4574
4575   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4576   round_type_str =
4577     format (0, "%U", format_policer_round_type, mp->round_type);
4578   type_str = format (0, "%U", format_policer_type, mp->type);
4579   conform_action_str = format (0, "%U", format_policer_action_type,
4580                                mp->conform_action_type);
4581   exceed_action_str = format (0, "%U", format_policer_action_type,
4582                               mp->exceed_action_type);
4583   violate_action_str = format (0, "%U", format_policer_action_type,
4584                                mp->violate_action_type);
4585
4586   if (VAT_JSON_ARRAY != vam->json_tree.type)
4587     {
4588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4589       vat_json_init_array (&vam->json_tree);
4590     }
4591   node = vat_json_array_add (&vam->json_tree);
4592
4593   vat_json_init_object (node);
4594   vat_json_object_add_string_copy (node, "name", mp->name);
4595   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4596   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4597   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4598   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4599   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4600   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4601   vat_json_object_add_string_copy (node, "type", type_str);
4602   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4603   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4604   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4605   vat_json_object_add_uint (node, "cir_tokens_per_period",
4606                             ntohl (mp->cir_tokens_per_period));
4607   vat_json_object_add_uint (node, "eir_tokens_per_period",
4608                             ntohl (mp->pir_tokens_per_period));
4609   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4610   vat_json_object_add_uint (node, "current_bucket",
4611                             ntohl (mp->current_bucket));
4612   vat_json_object_add_uint (node, "extended_limit",
4613                             ntohl (mp->extended_limit));
4614   vat_json_object_add_uint (node, "extended_bucket",
4615                             ntohl (mp->extended_bucket));
4616   vat_json_object_add_uint (node, "last_update_time",
4617                             ntohl (mp->last_update_time));
4618   vat_json_object_add_string_copy (node, "conform_action",
4619                                    conform_action_str);
4620   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4621     {
4622       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4623       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4624       vec_free (dscp_str);
4625     }
4626   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4627   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4628     {
4629       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4630       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4631       vec_free (dscp_str);
4632     }
4633   vat_json_object_add_string_copy (node, "violate_action",
4634                                    violate_action_str);
4635   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4638       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641
4642   vec_free (rate_type_str);
4643   vec_free (round_type_str);
4644   vec_free (type_str);
4645   vec_free (conform_action_str);
4646   vec_free (exceed_action_str);
4647   vec_free (violate_action_str);
4648 }
4649
4650 static void
4651 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4652                                            mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   int i, count = ntohl (mp->count);
4656
4657   if (count > 0)
4658     print (vam->ofp, "classify table ids (%d) : ", count);
4659   for (i = 0; i < count; i++)
4660     {
4661       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4662       print (vam->ofp, (i < count - 1) ? "," : "");
4663     }
4664   vam->retval = ntohl (mp->retval);
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_classify_table_ids_reply_t_handler_json
4670   (vl_api_classify_table_ids_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   int i, count = ntohl (mp->count);
4674
4675   if (count > 0)
4676     {
4677       vat_json_node_t node;
4678
4679       vat_json_init_object (&node);
4680       for (i = 0; i < count; i++)
4681         {
4682           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4683         }
4684       vat_json_print (vam->ofp, &node);
4685       vat_json_free (&node);
4686     }
4687   vam->retval = ntohl (mp->retval);
4688   vam->result_ready = 1;
4689 }
4690
4691 static void
4692   vl_api_classify_table_by_interface_reply_t_handler
4693   (vl_api_classify_table_by_interface_reply_t * mp)
4694 {
4695   vat_main_t *vam = &vat_main;
4696   u32 table_id;
4697
4698   table_id = ntohl (mp->l2_table_id);
4699   if (table_id != ~0)
4700     print (vam->ofp, "l2 table id : %d", table_id);
4701   else
4702     print (vam->ofp, "l2 table id : No input ACL tables configured");
4703   table_id = ntohl (mp->ip4_table_id);
4704   if (table_id != ~0)
4705     print (vam->ofp, "ip4 table id : %d", table_id);
4706   else
4707     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4708   table_id = ntohl (mp->ip6_table_id);
4709   if (table_id != ~0)
4710     print (vam->ofp, "ip6 table id : %d", table_id);
4711   else
4712     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4713   vam->retval = ntohl (mp->retval);
4714   vam->result_ready = 1;
4715 }
4716
4717 static void
4718   vl_api_classify_table_by_interface_reply_t_handler_json
4719   (vl_api_classify_table_by_interface_reply_t * mp)
4720 {
4721   vat_main_t *vam = &vat_main;
4722   vat_json_node_t node;
4723
4724   vat_json_init_object (&node);
4725
4726   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4727   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4728   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4729
4730   vat_json_print (vam->ofp, &node);
4731   vat_json_free (&node);
4732
4733   vam->retval = ntohl (mp->retval);
4734   vam->result_ready = 1;
4735 }
4736
4737 static void vl_api_policer_add_del_reply_t_handler
4738   (vl_api_policer_add_del_reply_t * mp)
4739 {
4740   vat_main_t *vam = &vat_main;
4741   i32 retval = ntohl (mp->retval);
4742   if (vam->async_mode)
4743     {
4744       vam->async_errors += (retval < 0);
4745     }
4746   else
4747     {
4748       vam->retval = retval;
4749       vam->result_ready = 1;
4750       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4751         /*
4752          * Note: this is just barely thread-safe, depends on
4753          * the main thread spinning waiting for an answer...
4754          */
4755         errmsg ("policer index %d", ntohl (mp->policer_index));
4756     }
4757 }
4758
4759 static void vl_api_policer_add_del_reply_t_handler_json
4760   (vl_api_policer_add_del_reply_t * mp)
4761 {
4762   vat_main_t *vam = &vat_main;
4763   vat_json_node_t node;
4764
4765   vat_json_init_object (&node);
4766   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4767   vat_json_object_add_uint (&node, "policer_index",
4768                             ntohl (mp->policer_index));
4769
4770   vat_json_print (vam->ofp, &node);
4771   vat_json_free (&node);
4772
4773   vam->retval = ntohl (mp->retval);
4774   vam->result_ready = 1;
4775 }
4776
4777 /* Format hex dump. */
4778 u8 *
4779 format_hex_bytes (u8 * s, va_list * va)
4780 {
4781   u8 *bytes = va_arg (*va, u8 *);
4782   int n_bytes = va_arg (*va, int);
4783   uword i;
4784
4785   /* Print short or long form depending on byte count. */
4786   uword short_form = n_bytes <= 32;
4787   u32 indent = format_get_indent (s);
4788
4789   if (n_bytes == 0)
4790     return s;
4791
4792   for (i = 0; i < n_bytes; i++)
4793     {
4794       if (!short_form && (i % 32) == 0)
4795         s = format (s, "%08x: ", i);
4796       s = format (s, "%02x", bytes[i]);
4797       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4798         s = format (s, "\n%U", format_white_space, indent);
4799     }
4800
4801   return s;
4802 }
4803
4804 static void
4805 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4806                                             * mp)
4807 {
4808   vat_main_t *vam = &vat_main;
4809   i32 retval = ntohl (mp->retval);
4810   if (retval == 0)
4811     {
4812       print (vam->ofp, "classify table info :");
4813       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4814              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4815              ntohl (mp->miss_next_index));
4816       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4817              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4818              ntohl (mp->match_n_vectors));
4819       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4820              ntohl (mp->mask_length));
4821     }
4822   vam->retval = retval;
4823   vam->result_ready = 1;
4824 }
4825
4826 static void
4827   vl_api_classify_table_info_reply_t_handler_json
4828   (vl_api_classify_table_info_reply_t * mp)
4829 {
4830   vat_main_t *vam = &vat_main;
4831   vat_json_node_t node;
4832
4833   i32 retval = ntohl (mp->retval);
4834   if (retval == 0)
4835     {
4836       vat_json_init_object (&node);
4837
4838       vat_json_object_add_int (&node, "sessions",
4839                                ntohl (mp->active_sessions));
4840       vat_json_object_add_int (&node, "nexttbl",
4841                                ntohl (mp->next_table_index));
4842       vat_json_object_add_int (&node, "nextnode",
4843                                ntohl (mp->miss_next_index));
4844       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4845       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4846       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4847       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4848                       ntohl (mp->mask_length), 0);
4849       vat_json_object_add_string_copy (&node, "mask", s);
4850
4851       vat_json_print (vam->ofp, &node);
4852       vat_json_free (&node);
4853     }
4854   vam->retval = ntohl (mp->retval);
4855   vam->result_ready = 1;
4856 }
4857
4858 static void
4859 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4860                                            mp)
4861 {
4862   vat_main_t *vam = &vat_main;
4863
4864   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4865          ntohl (mp->hit_next_index), ntohl (mp->advance),
4866          ntohl (mp->opaque_index));
4867   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4868          ntohl (mp->match_length));
4869 }
4870
4871 static void
4872   vl_api_classify_session_details_t_handler_json
4873   (vl_api_classify_session_details_t * mp)
4874 {
4875   vat_main_t *vam = &vat_main;
4876   vat_json_node_t *node = NULL;
4877
4878   if (VAT_JSON_ARRAY != vam->json_tree.type)
4879     {
4880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4881       vat_json_init_array (&vam->json_tree);
4882     }
4883   node = vat_json_array_add (&vam->json_tree);
4884
4885   vat_json_init_object (node);
4886   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4887   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4888   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4889   u8 *s =
4890     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4891             0);
4892   vat_json_object_add_string_copy (node, "match", s);
4893 }
4894
4895 static void vl_api_pg_create_interface_reply_t_handler
4896   (vl_api_pg_create_interface_reply_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899
4900   vam->retval = ntohl (mp->retval);
4901   vam->result_ready = 1;
4902 }
4903
4904 static void vl_api_pg_create_interface_reply_t_handler_json
4905   (vl_api_pg_create_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   i32 retval = ntohl (mp->retval);
4911   if (retval == 0)
4912     {
4913       vat_json_init_object (&node);
4914
4915       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4916
4917       vat_json_print (vam->ofp, &node);
4918       vat_json_free (&node);
4919     }
4920   vam->retval = ntohl (mp->retval);
4921   vam->result_ready = 1;
4922 }
4923
4924 static void vl_api_policer_classify_details_t_handler
4925   (vl_api_policer_classify_details_t * mp)
4926 {
4927   vat_main_t *vam = &vat_main;
4928
4929   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4930          ntohl (mp->table_index));
4931 }
4932
4933 static void vl_api_policer_classify_details_t_handler_json
4934   (vl_api_policer_classify_details_t * mp)
4935 {
4936   vat_main_t *vam = &vat_main;
4937   vat_json_node_t *node;
4938
4939   if (VAT_JSON_ARRAY != vam->json_tree.type)
4940     {
4941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4942       vat_json_init_array (&vam->json_tree);
4943     }
4944   node = vat_json_array_add (&vam->json_tree);
4945
4946   vat_json_init_object (node);
4947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4948   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4949 }
4950
4951 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4952   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955   i32 retval = ntohl (mp->retval);
4956   if (vam->async_mode)
4957     {
4958       vam->async_errors += (retval < 0);
4959     }
4960   else
4961     {
4962       vam->retval = retval;
4963       vam->sw_if_index = ntohl (mp->sw_if_index);
4964       vam->result_ready = 1;
4965     }
4966 }
4967
4968 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4969   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t node;
4973
4974   vat_json_init_object (&node);
4975   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4976   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4977
4978   vat_json_print (vam->ofp, &node);
4979   vat_json_free (&node);
4980
4981   vam->retval = ntohl (mp->retval);
4982   vam->result_ready = 1;
4983 }
4984
4985 static void vl_api_flow_classify_details_t_handler
4986   (vl_api_flow_classify_details_t * mp)
4987 {
4988   vat_main_t *vam = &vat_main;
4989
4990   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4991          ntohl (mp->table_index));
4992 }
4993
4994 static void vl_api_flow_classify_details_t_handler_json
4995   (vl_api_flow_classify_details_t * mp)
4996 {
4997   vat_main_t *vam = &vat_main;
4998   vat_json_node_t *node;
4999
5000   if (VAT_JSON_ARRAY != vam->json_tree.type)
5001     {
5002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5003       vat_json_init_array (&vam->json_tree);
5004     }
5005   node = vat_json_array_add (&vam->json_tree);
5006
5007   vat_json_init_object (node);
5008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5009   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5010 }
5011
5012 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5013 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5014 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5015 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5016 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5017 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5018 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5019 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5020 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5021 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5022 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5023 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5024 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5025 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5026 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5031 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5032 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5033 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5034
5035 /*
5036  * Generate boilerplate reply handlers, which
5037  * dig the return value out of the xxx_reply_t API message,
5038  * stick it into vam->retval, and set vam->result_ready
5039  *
5040  * Could also do this by pointing N message decode slots at
5041  * a single function, but that could break in subtle ways.
5042  */
5043
5044 #define foreach_standard_reply_retval_handler           \
5045 _(sw_interface_set_flags_reply)                         \
5046 _(sw_interface_add_del_address_reply)                   \
5047 _(sw_interface_set_rx_mode_reply)                       \
5048 _(sw_interface_set_table_reply)                         \
5049 _(sw_interface_set_mpls_enable_reply)                   \
5050 _(sw_interface_set_vpath_reply)                         \
5051 _(sw_interface_set_vxlan_bypass_reply)                  \
5052 _(sw_interface_set_geneve_bypass_reply)                 \
5053 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5054 _(sw_interface_set_l2_bridge_reply)                     \
5055 _(bridge_domain_add_del_reply)                          \
5056 _(sw_interface_set_l2_xconnect_reply)                   \
5057 _(l2fib_add_del_reply)                                  \
5058 _(l2fib_flush_int_reply)                                \
5059 _(l2fib_flush_bd_reply)                                 \
5060 _(ip_add_del_route_reply)                               \
5061 _(ip_table_add_del_reply)                               \
5062 _(ip_mroute_add_del_reply)                              \
5063 _(mpls_route_add_del_reply)                             \
5064 _(mpls_table_add_del_reply)                             \
5065 _(mpls_ip_bind_unbind_reply)                            \
5066 _(proxy_arp_add_del_reply)                              \
5067 _(proxy_arp_intfc_enable_disable_reply)                 \
5068 _(sw_interface_set_unnumbered_reply)                    \
5069 _(ip_neighbor_add_del_reply)                            \
5070 _(reset_vrf_reply)                                      \
5071 _(oam_add_del_reply)                                    \
5072 _(reset_fib_reply)                                      \
5073 _(dhcp_proxy_config_reply)                              \
5074 _(dhcp_proxy_set_vss_reply)                             \
5075 _(dhcp_client_config_reply)                             \
5076 _(set_ip_flow_hash_reply)                               \
5077 _(sw_interface_ip6_enable_disable_reply)                \
5078 _(sw_interface_ip6_set_link_local_address_reply)        \
5079 _(ip6nd_proxy_add_del_reply)                            \
5080 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5081 _(sw_interface_ip6nd_ra_config_reply)                   \
5082 _(set_arp_neighbor_limit_reply)                         \
5083 _(l2_patch_add_del_reply)                               \
5084 _(sr_policy_add_reply)                                  \
5085 _(sr_policy_mod_reply)                                  \
5086 _(sr_policy_del_reply)                                  \
5087 _(sr_localsid_add_del_reply)                            \
5088 _(sr_steering_add_del_reply)                            \
5089 _(classify_add_del_session_reply)                       \
5090 _(classify_set_interface_ip_table_reply)                \
5091 _(classify_set_interface_l2_tables_reply)               \
5092 _(l2tpv3_set_tunnel_cookies_reply)                      \
5093 _(l2tpv3_interface_enable_disable_reply)                \
5094 _(l2tpv3_set_lookup_key_reply)                          \
5095 _(l2_fib_clear_table_reply)                             \
5096 _(l2_interface_efp_filter_reply)                        \
5097 _(l2_interface_vlan_tag_rewrite_reply)                  \
5098 _(modify_vhost_user_if_reply)                           \
5099 _(delete_vhost_user_if_reply)                           \
5100 _(want_ip4_arp_events_reply)                            \
5101 _(want_ip6_nd_events_reply)                             \
5102 _(want_l2_macs_events_reply)                            \
5103 _(input_acl_set_interface_reply)                        \
5104 _(ipsec_spd_add_del_reply)                              \
5105 _(ipsec_interface_add_del_spd_reply)                    \
5106 _(ipsec_spd_add_del_entry_reply)                        \
5107 _(ipsec_sad_add_del_entry_reply)                        \
5108 _(ipsec_sa_set_key_reply)                               \
5109 _(ipsec_tunnel_if_add_del_reply)                        \
5110 _(ipsec_tunnel_if_set_key_reply)                        \
5111 _(ipsec_tunnel_if_set_sa_reply)                         \
5112 _(ikev2_profile_add_del_reply)                          \
5113 _(ikev2_profile_set_auth_reply)                         \
5114 _(ikev2_profile_set_id_reply)                           \
5115 _(ikev2_profile_set_ts_reply)                           \
5116 _(ikev2_set_local_key_reply)                            \
5117 _(ikev2_set_responder_reply)                            \
5118 _(ikev2_set_ike_transforms_reply)                       \
5119 _(ikev2_set_esp_transforms_reply)                       \
5120 _(ikev2_set_sa_lifetime_reply)                          \
5121 _(ikev2_initiate_sa_init_reply)                         \
5122 _(ikev2_initiate_del_ike_sa_reply)                      \
5123 _(ikev2_initiate_del_child_sa_reply)                    \
5124 _(ikev2_initiate_rekey_child_sa_reply)                  \
5125 _(delete_loopback_reply)                                \
5126 _(bd_ip_mac_add_del_reply)                              \
5127 _(map_del_domain_reply)                                 \
5128 _(map_add_del_rule_reply)                               \
5129 _(want_interface_events_reply)                          \
5130 _(want_stats_reply)                                     \
5131 _(cop_interface_enable_disable_reply)                   \
5132 _(cop_whitelist_enable_disable_reply)                   \
5133 _(sw_interface_clear_stats_reply)                       \
5134 _(ioam_enable_reply)                                    \
5135 _(ioam_disable_reply)                                   \
5136 _(one_add_del_locator_reply)                            \
5137 _(one_add_del_local_eid_reply)                          \
5138 _(one_add_del_remote_mapping_reply)                     \
5139 _(one_add_del_adjacency_reply)                          \
5140 _(one_add_del_map_resolver_reply)                       \
5141 _(one_add_del_map_server_reply)                         \
5142 _(one_enable_disable_reply)                             \
5143 _(one_rloc_probe_enable_disable_reply)                  \
5144 _(one_map_register_enable_disable_reply)                \
5145 _(one_map_register_set_ttl_reply)                       \
5146 _(one_set_transport_protocol_reply)                     \
5147 _(one_map_register_fallback_threshold_reply)            \
5148 _(one_pitr_set_locator_set_reply)                       \
5149 _(one_map_request_mode_reply)                           \
5150 _(one_add_del_map_request_itr_rlocs_reply)              \
5151 _(one_eid_table_add_del_map_reply)                      \
5152 _(one_use_petr_reply)                                   \
5153 _(one_stats_enable_disable_reply)                       \
5154 _(one_add_del_l2_arp_entry_reply)                       \
5155 _(one_add_del_ndp_entry_reply)                          \
5156 _(one_stats_flush_reply)                                \
5157 _(gpe_enable_disable_reply)                             \
5158 _(gpe_set_encap_mode_reply)                             \
5159 _(gpe_add_del_iface_reply)                              \
5160 _(gpe_add_del_native_fwd_rpath_reply)                   \
5161 _(af_packet_delete_reply)                               \
5162 _(policer_classify_set_interface_reply)                 \
5163 _(netmap_create_reply)                                  \
5164 _(netmap_delete_reply)                                  \
5165 _(set_ipfix_exporter_reply)                             \
5166 _(set_ipfix_classify_stream_reply)                      \
5167 _(ipfix_classify_table_add_del_reply)                   \
5168 _(flow_classify_set_interface_reply)                    \
5169 _(sw_interface_span_enable_disable_reply)               \
5170 _(pg_capture_reply)                                     \
5171 _(pg_enable_disable_reply)                              \
5172 _(ip_source_and_port_range_check_add_del_reply)         \
5173 _(ip_source_and_port_range_check_interface_add_del_reply)\
5174 _(delete_subif_reply)                                   \
5175 _(l2_interface_pbb_tag_rewrite_reply)                   \
5176 _(punt_reply)                                           \
5177 _(feature_enable_disable_reply)                         \
5178 _(sw_interface_tag_add_del_reply)                       \
5179 _(sw_interface_set_mtu_reply)                           \
5180 _(p2p_ethernet_add_reply)                               \
5181 _(p2p_ethernet_del_reply)                               \
5182 _(lldp_config_reply)                                    \
5183 _(sw_interface_set_lldp_reply)                          \
5184 _(tcp_configure_src_addresses_reply)                    \
5185 _(app_namespace_add_del_reply)                          \
5186 _(dns_enable_disable_reply)                             \
5187 _(dns_name_server_add_del_reply)                        \
5188 _(session_rule_add_del_reply)
5189
5190 #define _(n)                                    \
5191     static void vl_api_##n##_t_handler          \
5192     (vl_api_##n##_t * mp)                       \
5193     {                                           \
5194         vat_main_t * vam = &vat_main;           \
5195         i32 retval = ntohl(mp->retval);         \
5196         if (vam->async_mode) {                  \
5197             vam->async_errors += (retval < 0);  \
5198         } else {                                \
5199             vam->retval = retval;               \
5200             vam->result_ready = 1;              \
5201         }                                       \
5202     }
5203 foreach_standard_reply_retval_handler;
5204 #undef _
5205
5206 #define _(n)                                    \
5207     static void vl_api_##n##_t_handler_json     \
5208     (vl_api_##n##_t * mp)                       \
5209     {                                           \
5210         vat_main_t * vam = &vat_main;           \
5211         vat_json_node_t node;                   \
5212         vat_json_init_object(&node);            \
5213         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5214         vat_json_print(vam->ofp, &node);        \
5215         vam->retval = ntohl(mp->retval);        \
5216         vam->result_ready = 1;                  \
5217     }
5218 foreach_standard_reply_retval_handler;
5219 #undef _
5220
5221 /*
5222  * Table of message reply handlers, must include boilerplate handlers
5223  * we just generated
5224  */
5225
5226 #define foreach_vpe_api_reply_msg                                       \
5227 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5228 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5229 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5230 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5231 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5232 _(CLI_REPLY, cli_reply)                                                 \
5233 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5234 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5235   sw_interface_add_del_address_reply)                                   \
5236 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5237 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5238 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5239 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5240 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5241 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5242 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5243 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5244   sw_interface_set_l2_xconnect_reply)                                   \
5245 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5246   sw_interface_set_l2_bridge_reply)                                     \
5247 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5248 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5249 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5250 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5251 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5252 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5253 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5254 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5255 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5256 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5257 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5258 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5259 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5260 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5261 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5262 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5263 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5264 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5265 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5266 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5267   proxy_arp_intfc_enable_disable_reply)                                 \
5268 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5269 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5270   sw_interface_set_unnumbered_reply)                                    \
5271 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5272 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5273 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5274 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5275 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5276 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5277 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5278 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5279 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5280 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5281 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5282 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5283   sw_interface_ip6_enable_disable_reply)                                \
5284 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5285   sw_interface_ip6_set_link_local_address_reply)                        \
5286 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5287 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5288 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5289   sw_interface_ip6nd_ra_prefix_reply)                                   \
5290 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5291   sw_interface_ip6nd_ra_config_reply)                                   \
5292 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5293 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5294 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5295 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5296 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5297 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5298 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5299 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5300 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5301 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5302 classify_set_interface_ip_table_reply)                                  \
5303 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5304   classify_set_interface_l2_tables_reply)                               \
5305 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5306 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5307 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5308 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5309 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5310   l2tpv3_interface_enable_disable_reply)                                \
5311 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5312 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5313 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5314 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5315 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5316 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5317 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5318 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5319 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5320 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5321 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5322 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5323 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5324 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5325 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5326 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5327 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5328 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5329 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5330 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5331 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5332 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5333 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5334 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5335 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5336 _(L2_MACS_EVENT, l2_macs_event)                                         \
5337 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5338 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5339 _(IP_DETAILS, ip_details)                                               \
5340 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5341 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5342 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5343 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5344 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5345 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5346 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5347 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5348 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5349 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5350 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5351 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5352 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5353 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5354 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5355 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5356 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5357 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5358 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5359 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5360 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5361 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5362 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5363 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5364 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5365 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5366 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5367 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5368 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5369 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5370 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5371 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5372 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5373 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5374 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5375 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5376 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5377 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5378 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5379 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5380 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5381 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5382 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5383 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5384 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5385 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5386 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5387 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5388   one_map_register_enable_disable_reply)                                \
5389 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5390 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5391 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5392 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5393   one_map_register_fallback_threshold_reply)                            \
5394 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5395   one_rloc_probe_enable_disable_reply)                                  \
5396 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5397 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5398 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5399 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5400 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5401 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5402 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5403 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5404 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5405 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5406 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5407 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5408 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5409 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5410 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5411 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5412   show_one_stats_enable_disable_reply)                                  \
5413 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5414 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5415 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5416 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5417 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5418 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5419 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5420 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5421 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5422 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5423 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5424 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5425 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5426 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5427 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5428   gpe_add_del_native_fwd_rpath_reply)                                   \
5429 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5430   gpe_fwd_entry_path_details)                                           \
5431 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5432 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5433   one_add_del_map_request_itr_rlocs_reply)                              \
5434 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5435   one_get_map_request_itr_rlocs_reply)                                  \
5436 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5437 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5438 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5439 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5440 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5442   show_one_map_register_state_reply)                                    \
5443 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5444 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5445   show_one_map_register_fallback_threshold_reply)                       \
5446 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5447 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5448 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5449 _(POLICER_DETAILS, policer_details)                                     \
5450 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5451 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5452 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5453 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5454 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5455 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5456 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5457 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5458 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5459 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5460 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5461 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5462 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5463 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5464 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5465 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5466 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5467 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5468 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5469 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5470 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5471 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5472 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5473 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5474 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5475  ip_source_and_port_range_check_add_del_reply)                          \
5476 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5477  ip_source_and_port_range_check_interface_add_del_reply)                \
5478 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5479 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5480 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5481 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5482 _(PUNT_REPLY, punt_reply)                                               \
5483 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5484 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5485 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5486 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5487 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5488 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5489 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5490 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5491 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5492 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5493 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5494 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5495 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5496 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5497 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5498 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5499 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5500 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5501 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)
5502
5503 #define foreach_standalone_reply_msg                                    \
5504 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5505 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5506 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5507 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5508 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5509 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5510 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5511 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5512
5513 typedef struct
5514 {
5515   u8 *name;
5516   u32 value;
5517 } name_sort_t;
5518
5519
5520 #define STR_VTR_OP_CASE(op)     \
5521     case L2_VTR_ ## op:         \
5522         return "" # op;
5523
5524 static const char *
5525 str_vtr_op (u32 vtr_op)
5526 {
5527   switch (vtr_op)
5528     {
5529       STR_VTR_OP_CASE (DISABLED);
5530       STR_VTR_OP_CASE (PUSH_1);
5531       STR_VTR_OP_CASE (PUSH_2);
5532       STR_VTR_OP_CASE (POP_1);
5533       STR_VTR_OP_CASE (POP_2);
5534       STR_VTR_OP_CASE (TRANSLATE_1_1);
5535       STR_VTR_OP_CASE (TRANSLATE_1_2);
5536       STR_VTR_OP_CASE (TRANSLATE_2_1);
5537       STR_VTR_OP_CASE (TRANSLATE_2_2);
5538     }
5539
5540   return "UNKNOWN";
5541 }
5542
5543 static int
5544 dump_sub_interface_table (vat_main_t * vam)
5545 {
5546   const sw_interface_subif_t *sub = NULL;
5547
5548   if (vam->json_output)
5549     {
5550       clib_warning
5551         ("JSON output supported only for VPE API calls and dump_stats_table");
5552       return -99;
5553     }
5554
5555   print (vam->ofp,
5556          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5557          "Interface", "sw_if_index",
5558          "sub id", "dot1ad", "tags", "outer id",
5559          "inner id", "exact", "default", "outer any", "inner any");
5560
5561   vec_foreach (sub, vam->sw_if_subif_table)
5562   {
5563     print (vam->ofp,
5564            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5565            sub->interface_name,
5566            sub->sw_if_index,
5567            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5568            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5569            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5570            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5571     if (sub->vtr_op != L2_VTR_DISABLED)
5572       {
5573         print (vam->ofp,
5574                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5575                "tag1: %d tag2: %d ]",
5576                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5577                sub->vtr_tag1, sub->vtr_tag2);
5578       }
5579   }
5580
5581   return 0;
5582 }
5583
5584 static int
5585 name_sort_cmp (void *a1, void *a2)
5586 {
5587   name_sort_t *n1 = a1;
5588   name_sort_t *n2 = a2;
5589
5590   return strcmp ((char *) n1->name, (char *) n2->name);
5591 }
5592
5593 static int
5594 dump_interface_table (vat_main_t * vam)
5595 {
5596   hash_pair_t *p;
5597   name_sort_t *nses = 0, *ns;
5598
5599   if (vam->json_output)
5600     {
5601       clib_warning
5602         ("JSON output supported only for VPE API calls and dump_stats_table");
5603       return -99;
5604     }
5605
5606   /* *INDENT-OFF* */
5607   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5608   ({
5609     vec_add2 (nses, ns, 1);
5610     ns->name = (u8 *)(p->key);
5611     ns->value = (u32) p->value[0];
5612   }));
5613   /* *INDENT-ON* */
5614
5615   vec_sort_with_function (nses, name_sort_cmp);
5616
5617   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5618   vec_foreach (ns, nses)
5619   {
5620     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5621   }
5622   vec_free (nses);
5623   return 0;
5624 }
5625
5626 static int
5627 dump_ip_table (vat_main_t * vam, int is_ipv6)
5628 {
5629   const ip_details_t *det = NULL;
5630   const ip_address_details_t *address = NULL;
5631   u32 i = ~0;
5632
5633   print (vam->ofp, "%-12s", "sw_if_index");
5634
5635   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5636   {
5637     i++;
5638     if (!det->present)
5639       {
5640         continue;
5641       }
5642     print (vam->ofp, "%-12d", i);
5643     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5644     if (!det->addr)
5645       {
5646         continue;
5647       }
5648     vec_foreach (address, det->addr)
5649     {
5650       print (vam->ofp,
5651              "            %-30U%-13d",
5652              is_ipv6 ? format_ip6_address : format_ip4_address,
5653              address->ip, address->prefix_length);
5654     }
5655   }
5656
5657   return 0;
5658 }
5659
5660 static int
5661 dump_ipv4_table (vat_main_t * vam)
5662 {
5663   if (vam->json_output)
5664     {
5665       clib_warning
5666         ("JSON output supported only for VPE API calls and dump_stats_table");
5667       return -99;
5668     }
5669
5670   return dump_ip_table (vam, 0);
5671 }
5672
5673 static int
5674 dump_ipv6_table (vat_main_t * vam)
5675 {
5676   if (vam->json_output)
5677     {
5678       clib_warning
5679         ("JSON output supported only for VPE API calls and dump_stats_table");
5680       return -99;
5681     }
5682
5683   return dump_ip_table (vam, 1);
5684 }
5685
5686 static char *
5687 counter_type_to_str (u8 counter_type, u8 is_combined)
5688 {
5689   if (!is_combined)
5690     {
5691       switch (counter_type)
5692         {
5693         case VNET_INTERFACE_COUNTER_DROP:
5694           return "drop";
5695         case VNET_INTERFACE_COUNTER_PUNT:
5696           return "punt";
5697         case VNET_INTERFACE_COUNTER_IP4:
5698           return "ip4";
5699         case VNET_INTERFACE_COUNTER_IP6:
5700           return "ip6";
5701         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5702           return "rx-no-buf";
5703         case VNET_INTERFACE_COUNTER_RX_MISS:
5704           return "rx-miss";
5705         case VNET_INTERFACE_COUNTER_RX_ERROR:
5706           return "rx-error";
5707         case VNET_INTERFACE_COUNTER_TX_ERROR:
5708           return "tx-error";
5709         default:
5710           return "INVALID-COUNTER-TYPE";
5711         }
5712     }
5713   else
5714     {
5715       switch (counter_type)
5716         {
5717         case VNET_INTERFACE_COUNTER_RX:
5718           return "rx";
5719         case VNET_INTERFACE_COUNTER_TX:
5720           return "tx";
5721         default:
5722           return "INVALID-COUNTER-TYPE";
5723         }
5724     }
5725 }
5726
5727 static int
5728 dump_stats_table (vat_main_t * vam)
5729 {
5730   vat_json_node_t node;
5731   vat_json_node_t *msg_array;
5732   vat_json_node_t *msg;
5733   vat_json_node_t *counter_array;
5734   vat_json_node_t *counter;
5735   interface_counter_t c;
5736   u64 packets;
5737   ip4_fib_counter_t *c4;
5738   ip6_fib_counter_t *c6;
5739   ip4_nbr_counter_t *n4;
5740   ip6_nbr_counter_t *n6;
5741   int i, j;
5742
5743   if (!vam->json_output)
5744     {
5745       clib_warning ("dump_stats_table supported only in JSON format");
5746       return -99;
5747     }
5748
5749   vat_json_init_object (&node);
5750
5751   /* interface counters */
5752   msg_array = vat_json_object_add (&node, "interface_counters");
5753   vat_json_init_array (msg_array);
5754   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5755     {
5756       msg = vat_json_array_add (msg_array);
5757       vat_json_init_object (msg);
5758       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5759                                        (u8 *) counter_type_to_str (i, 0));
5760       vat_json_object_add_int (msg, "is_combined", 0);
5761       counter_array = vat_json_object_add (msg, "data");
5762       vat_json_init_array (counter_array);
5763       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5764         {
5765           packets = vam->simple_interface_counters[i][j];
5766           vat_json_array_add_uint (counter_array, packets);
5767         }
5768     }
5769   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5770     {
5771       msg = vat_json_array_add (msg_array);
5772       vat_json_init_object (msg);
5773       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5774                                        (u8 *) counter_type_to_str (i, 1));
5775       vat_json_object_add_int (msg, "is_combined", 1);
5776       counter_array = vat_json_object_add (msg, "data");
5777       vat_json_init_array (counter_array);
5778       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5779         {
5780           c = vam->combined_interface_counters[i][j];
5781           counter = vat_json_array_add (counter_array);
5782           vat_json_init_object (counter);
5783           vat_json_object_add_uint (counter, "packets", c.packets);
5784           vat_json_object_add_uint (counter, "bytes", c.bytes);
5785         }
5786     }
5787
5788   /* ip4 fib counters */
5789   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5790   vat_json_init_array (msg_array);
5791   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5792     {
5793       msg = vat_json_array_add (msg_array);
5794       vat_json_init_object (msg);
5795       vat_json_object_add_uint (msg, "vrf_id",
5796                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5797       counter_array = vat_json_object_add (msg, "c");
5798       vat_json_init_array (counter_array);
5799       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5800         {
5801           counter = vat_json_array_add (counter_array);
5802           vat_json_init_object (counter);
5803           c4 = &vam->ip4_fib_counters[i][j];
5804           vat_json_object_add_ip4 (counter, "address", c4->address);
5805           vat_json_object_add_uint (counter, "address_length",
5806                                     c4->address_length);
5807           vat_json_object_add_uint (counter, "packets", c4->packets);
5808           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5809         }
5810     }
5811
5812   /* ip6 fib counters */
5813   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5814   vat_json_init_array (msg_array);
5815   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5816     {
5817       msg = vat_json_array_add (msg_array);
5818       vat_json_init_object (msg);
5819       vat_json_object_add_uint (msg, "vrf_id",
5820                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5821       counter_array = vat_json_object_add (msg, "c");
5822       vat_json_init_array (counter_array);
5823       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5824         {
5825           counter = vat_json_array_add (counter_array);
5826           vat_json_init_object (counter);
5827           c6 = &vam->ip6_fib_counters[i][j];
5828           vat_json_object_add_ip6 (counter, "address", c6->address);
5829           vat_json_object_add_uint (counter, "address_length",
5830                                     c6->address_length);
5831           vat_json_object_add_uint (counter, "packets", c6->packets);
5832           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5833         }
5834     }
5835
5836   /* ip4 nbr counters */
5837   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5838   vat_json_init_array (msg_array);
5839   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5840     {
5841       msg = vat_json_array_add (msg_array);
5842       vat_json_init_object (msg);
5843       vat_json_object_add_uint (msg, "sw_if_index", i);
5844       counter_array = vat_json_object_add (msg, "c");
5845       vat_json_init_array (counter_array);
5846       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5847         {
5848           counter = vat_json_array_add (counter_array);
5849           vat_json_init_object (counter);
5850           n4 = &vam->ip4_nbr_counters[i][j];
5851           vat_json_object_add_ip4 (counter, "address", n4->address);
5852           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5853           vat_json_object_add_uint (counter, "packets", n4->packets);
5854           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5855         }
5856     }
5857
5858   /* ip6 nbr counters */
5859   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5860   vat_json_init_array (msg_array);
5861   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5862     {
5863       msg = vat_json_array_add (msg_array);
5864       vat_json_init_object (msg);
5865       vat_json_object_add_uint (msg, "sw_if_index", i);
5866       counter_array = vat_json_object_add (msg, "c");
5867       vat_json_init_array (counter_array);
5868       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5869         {
5870           counter = vat_json_array_add (counter_array);
5871           vat_json_init_object (counter);
5872           n6 = &vam->ip6_nbr_counters[i][j];
5873           vat_json_object_add_ip6 (counter, "address", n6->address);
5874           vat_json_object_add_uint (counter, "packets", n6->packets);
5875           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5876         }
5877     }
5878
5879   vat_json_print (vam->ofp, &node);
5880   vat_json_free (&node);
5881
5882   return 0;
5883 }
5884
5885 /*
5886  * Pass CLI buffers directly in the CLI_INBAND API message,
5887  * instead of an additional shared memory area.
5888  */
5889 static int
5890 exec_inband (vat_main_t * vam)
5891 {
5892   vl_api_cli_inband_t *mp;
5893   unformat_input_t *i = vam->input;
5894   int ret;
5895
5896   if (vec_len (i->buffer) == 0)
5897     return -1;
5898
5899   if (vam->exec_mode == 0 && unformat (i, "mode"))
5900     {
5901       vam->exec_mode = 1;
5902       return 0;
5903     }
5904   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5905     {
5906       vam->exec_mode = 0;
5907       return 0;
5908     }
5909
5910   /*
5911    * In order for the CLI command to work, it
5912    * must be a vector ending in \n, not a C-string ending
5913    * in \n\0.
5914    */
5915   u32 len = vec_len (vam->input->buffer);
5916   M2 (CLI_INBAND, mp, len);
5917   clib_memcpy (mp->cmd, vam->input->buffer, len);
5918   mp->length = htonl (len);
5919
5920   S (mp);
5921   W (ret);
5922   /* json responses may or may not include a useful reply... */
5923   if (vec_len (vam->cmd_reply))
5924     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5925   return ret;
5926 }
5927
5928 int
5929 exec (vat_main_t * vam)
5930 {
5931   return exec_inband (vam);
5932 }
5933
5934 static int
5935 api_create_loopback (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_create_loopback_t *mp;
5939   vl_api_create_loopback_instance_t *mp_lbi;
5940   u8 mac_address[6];
5941   u8 mac_set = 0;
5942   u8 is_specified = 0;
5943   u32 user_instance = 0;
5944   int ret;
5945
5946   memset (mac_address, 0, sizeof (mac_address));
5947
5948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949     {
5950       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5951         mac_set = 1;
5952       if (unformat (i, "instance %d", &user_instance))
5953         is_specified = 1;
5954       else
5955         break;
5956     }
5957
5958   if (is_specified)
5959     {
5960       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5961       mp_lbi->is_specified = is_specified;
5962       if (is_specified)
5963         mp_lbi->user_instance = htonl (user_instance);
5964       if (mac_set)
5965         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5966       S (mp_lbi);
5967     }
5968   else
5969     {
5970       /* Construct the API message */
5971       M (CREATE_LOOPBACK, mp);
5972       if (mac_set)
5973         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5974       S (mp);
5975     }
5976
5977   W (ret);
5978   return ret;
5979 }
5980
5981 static int
5982 api_delete_loopback (vat_main_t * vam)
5983 {
5984   unformat_input_t *i = vam->input;
5985   vl_api_delete_loopback_t *mp;
5986   u32 sw_if_index = ~0;
5987   int ret;
5988
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "sw_if_index %d", &sw_if_index))
5992         ;
5993       else
5994         break;
5995     }
5996
5997   if (sw_if_index == ~0)
5998     {
5999       errmsg ("missing sw_if_index");
6000       return -99;
6001     }
6002
6003   /* Construct the API message */
6004   M (DELETE_LOOPBACK, mp);
6005   mp->sw_if_index = ntohl (sw_if_index);
6006
6007   S (mp);
6008   W (ret);
6009   return ret;
6010 }
6011
6012 static int
6013 api_want_stats (vat_main_t * vam)
6014 {
6015   unformat_input_t *i = vam->input;
6016   vl_api_want_stats_t *mp;
6017   int enable = -1;
6018   int ret;
6019
6020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6021     {
6022       if (unformat (i, "enable"))
6023         enable = 1;
6024       else if (unformat (i, "disable"))
6025         enable = 0;
6026       else
6027         break;
6028     }
6029
6030   if (enable == -1)
6031     {
6032       errmsg ("missing enable|disable");
6033       return -99;
6034     }
6035
6036   M (WANT_STATS, mp);
6037   mp->enable_disable = enable;
6038
6039   S (mp);
6040   W (ret);
6041   return ret;
6042 }
6043
6044 static int
6045 api_want_interface_events (vat_main_t * vam)
6046 {
6047   unformat_input_t *i = vam->input;
6048   vl_api_want_interface_events_t *mp;
6049   int enable = -1;
6050   int ret;
6051
6052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6053     {
6054       if (unformat (i, "enable"))
6055         enable = 1;
6056       else if (unformat (i, "disable"))
6057         enable = 0;
6058       else
6059         break;
6060     }
6061
6062   if (enable == -1)
6063     {
6064       errmsg ("missing enable|disable");
6065       return -99;
6066     }
6067
6068   M (WANT_INTERFACE_EVENTS, mp);
6069   mp->enable_disable = enable;
6070
6071   vam->interface_event_display = enable;
6072
6073   S (mp);
6074   W (ret);
6075   return ret;
6076 }
6077
6078
6079 /* Note: non-static, called once to set up the initial intfc table */
6080 int
6081 api_sw_interface_dump (vat_main_t * vam)
6082 {
6083   vl_api_sw_interface_dump_t *mp;
6084   vl_api_control_ping_t *mp_ping;
6085   hash_pair_t *p;
6086   name_sort_t *nses = 0, *ns;
6087   sw_interface_subif_t *sub = NULL;
6088   int ret;
6089
6090   /* Toss the old name table */
6091   /* *INDENT-OFF* */
6092   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6093   ({
6094     vec_add2 (nses, ns, 1);
6095     ns->name = (u8 *)(p->key);
6096     ns->value = (u32) p->value[0];
6097   }));
6098   /* *INDENT-ON* */
6099
6100   hash_free (vam->sw_if_index_by_interface_name);
6101
6102   vec_foreach (ns, nses) vec_free (ns->name);
6103
6104   vec_free (nses);
6105
6106   vec_foreach (sub, vam->sw_if_subif_table)
6107   {
6108     vec_free (sub->interface_name);
6109   }
6110   vec_free (vam->sw_if_subif_table);
6111
6112   /* recreate the interface name hash table */
6113   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6114
6115   /* Get list of ethernets */
6116   M (SW_INTERFACE_DUMP, mp);
6117   mp->name_filter_valid = 1;
6118   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6119   S (mp);
6120
6121   /* and local / loopback interfaces */
6122   M (SW_INTERFACE_DUMP, mp);
6123   mp->name_filter_valid = 1;
6124   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6125   S (mp);
6126
6127   /* and packet-generator interfaces */
6128   M (SW_INTERFACE_DUMP, mp);
6129   mp->name_filter_valid = 1;
6130   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6131   S (mp);
6132
6133   /* and vxlan-gpe tunnel interfaces */
6134   M (SW_INTERFACE_DUMP, mp);
6135   mp->name_filter_valid = 1;
6136   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6137            sizeof (mp->name_filter) - 1);
6138   S (mp);
6139
6140   /* and vxlan tunnel interfaces */
6141   M (SW_INTERFACE_DUMP, mp);
6142   mp->name_filter_valid = 1;
6143   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6144   S (mp);
6145
6146   /* and geneve tunnel interfaces */
6147   M (SW_INTERFACE_DUMP, mp);
6148   mp->name_filter_valid = 1;
6149   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6150   S (mp);
6151
6152   /* and host (af_packet) interfaces */
6153   M (SW_INTERFACE_DUMP, mp);
6154   mp->name_filter_valid = 1;
6155   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6156   S (mp);
6157
6158   /* and l2tpv3 tunnel interfaces */
6159   M (SW_INTERFACE_DUMP, mp);
6160   mp->name_filter_valid = 1;
6161   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6162            sizeof (mp->name_filter) - 1);
6163   S (mp);
6164
6165   /* and GRE tunnel interfaces */
6166   M (SW_INTERFACE_DUMP, mp);
6167   mp->name_filter_valid = 1;
6168   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6169   S (mp);
6170
6171   /* and LISP-GPE interfaces */
6172   M (SW_INTERFACE_DUMP, mp);
6173   mp->name_filter_valid = 1;
6174   strncpy ((char *) mp->name_filter, "lisp_gpe",
6175            sizeof (mp->name_filter) - 1);
6176   S (mp);
6177
6178   /* and IPSEC tunnel interfaces */
6179   M (SW_INTERFACE_DUMP, mp);
6180   mp->name_filter_valid = 1;
6181   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6182   S (mp);
6183
6184   /* Use a control ping for synchronization */
6185   MPING (CONTROL_PING, mp_ping);
6186   S (mp_ping);
6187
6188   W (ret);
6189   return ret;
6190 }
6191
6192 static int
6193 api_sw_interface_set_flags (vat_main_t * vam)
6194 {
6195   unformat_input_t *i = vam->input;
6196   vl_api_sw_interface_set_flags_t *mp;
6197   u32 sw_if_index;
6198   u8 sw_if_index_set = 0;
6199   u8 admin_up = 0;
6200   int ret;
6201
6202   /* Parse args required to build the message */
6203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6204     {
6205       if (unformat (i, "admin-up"))
6206         admin_up = 1;
6207       else if (unformat (i, "admin-down"))
6208         admin_up = 0;
6209       else
6210         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6211         sw_if_index_set = 1;
6212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6213         sw_if_index_set = 1;
6214       else
6215         break;
6216     }
6217
6218   if (sw_if_index_set == 0)
6219     {
6220       errmsg ("missing interface name or sw_if_index");
6221       return -99;
6222     }
6223
6224   /* Construct the API message */
6225   M (SW_INTERFACE_SET_FLAGS, mp);
6226   mp->sw_if_index = ntohl (sw_if_index);
6227   mp->admin_up_down = admin_up;
6228
6229   /* send it... */
6230   S (mp);
6231
6232   /* Wait for a reply, return the good/bad news... */
6233   W (ret);
6234   return ret;
6235 }
6236
6237 static int
6238 api_sw_interface_set_rx_mode (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_sw_interface_set_rx_mode_t *mp;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244   int ret;
6245   u8 queue_id_valid = 0;
6246   u32 queue_id;
6247   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "queue %d", &queue_id))
6253         queue_id_valid = 1;
6254       else if (unformat (i, "polling"))
6255         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6256       else if (unformat (i, "interrupt"))
6257         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6258       else if (unformat (i, "adaptive"))
6259         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6260       else
6261         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6264         sw_if_index_set = 1;
6265       else
6266         break;
6267     }
6268
6269   if (sw_if_index_set == 0)
6270     {
6271       errmsg ("missing interface name or sw_if_index");
6272       return -99;
6273     }
6274   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6275     {
6276       errmsg ("missing rx-mode");
6277       return -99;
6278     }
6279
6280   /* Construct the API message */
6281   M (SW_INTERFACE_SET_RX_MODE, mp);
6282   mp->sw_if_index = ntohl (sw_if_index);
6283   mp->mode = mode;
6284   mp->queue_id_valid = queue_id_valid;
6285   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6286
6287   /* send it... */
6288   S (mp);
6289
6290   /* Wait for a reply, return the good/bad news... */
6291   W (ret);
6292   return ret;
6293 }
6294
6295 static int
6296 api_sw_interface_clear_stats (vat_main_t * vam)
6297 {
6298   unformat_input_t *i = vam->input;
6299   vl_api_sw_interface_clear_stats_t *mp;
6300   u32 sw_if_index;
6301   u8 sw_if_index_set = 0;
6302   int ret;
6303
6304   /* Parse args required to build the message */
6305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6306     {
6307       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6310         sw_if_index_set = 1;
6311       else
6312         break;
6313     }
6314
6315   /* Construct the API message */
6316   M (SW_INTERFACE_CLEAR_STATS, mp);
6317
6318   if (sw_if_index_set == 1)
6319     mp->sw_if_index = ntohl (sw_if_index);
6320   else
6321     mp->sw_if_index = ~0;
6322
6323   /* send it... */
6324   S (mp);
6325
6326   /* Wait for a reply, return the good/bad news... */
6327   W (ret);
6328   return ret;
6329 }
6330
6331 static int
6332 api_sw_interface_add_del_address (vat_main_t * vam)
6333 {
6334   unformat_input_t *i = vam->input;
6335   vl_api_sw_interface_add_del_address_t *mp;
6336   u32 sw_if_index;
6337   u8 sw_if_index_set = 0;
6338   u8 is_add = 1, del_all = 0;
6339   u32 address_length = 0;
6340   u8 v4_address_set = 0;
6341   u8 v6_address_set = 0;
6342   ip4_address_t v4address;
6343   ip6_address_t v6address;
6344   int ret;
6345
6346   /* Parse args required to build the message */
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "del-all"))
6350         del_all = 1;
6351       else if (unformat (i, "del"))
6352         is_add = 0;
6353       else
6354         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6355         sw_if_index_set = 1;
6356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "%U/%d",
6359                          unformat_ip4_address, &v4address, &address_length))
6360         v4_address_set = 1;
6361       else if (unformat (i, "%U/%d",
6362                          unformat_ip6_address, &v6address, &address_length))
6363         v6_address_set = 1;
6364       else
6365         break;
6366     }
6367
6368   if (sw_if_index_set == 0)
6369     {
6370       errmsg ("missing interface name or sw_if_index");
6371       return -99;
6372     }
6373   if (v4_address_set && v6_address_set)
6374     {
6375       errmsg ("both v4 and v6 addresses set");
6376       return -99;
6377     }
6378   if (!v4_address_set && !v6_address_set && !del_all)
6379     {
6380       errmsg ("no addresses set");
6381       return -99;
6382     }
6383
6384   /* Construct the API message */
6385   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6386
6387   mp->sw_if_index = ntohl (sw_if_index);
6388   mp->is_add = is_add;
6389   mp->del_all = del_all;
6390   if (v6_address_set)
6391     {
6392       mp->is_ipv6 = 1;
6393       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6394     }
6395   else
6396     {
6397       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6398     }
6399   mp->address_length = address_length;
6400
6401   /* send it... */
6402   S (mp);
6403
6404   /* Wait for a reply, return good/bad news  */
6405   W (ret);
6406   return ret;
6407 }
6408
6409 static int
6410 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6411 {
6412   unformat_input_t *i = vam->input;
6413   vl_api_sw_interface_set_mpls_enable_t *mp;
6414   u32 sw_if_index;
6415   u8 sw_if_index_set = 0;
6416   u8 enable = 1;
6417   int ret;
6418
6419   /* Parse args required to build the message */
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6423         sw_if_index_set = 1;
6424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6425         sw_if_index_set = 1;
6426       else if (unformat (i, "disable"))
6427         enable = 0;
6428       else if (unformat (i, "dis"))
6429         enable = 0;
6430       else
6431         break;
6432     }
6433
6434   if (sw_if_index_set == 0)
6435     {
6436       errmsg ("missing interface name or sw_if_index");
6437       return -99;
6438     }
6439
6440   /* Construct the API message */
6441   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6442
6443   mp->sw_if_index = ntohl (sw_if_index);
6444   mp->enable = enable;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_set_table (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_set_table_t *mp;
6459   u32 sw_if_index, vrf_id = 0;
6460   u8 sw_if_index_set = 0;
6461   u8 is_ipv6 = 0;
6462   int ret;
6463
6464   /* Parse args required to build the message */
6465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6466     {
6467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6468         sw_if_index_set = 1;
6469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6470         sw_if_index_set = 1;
6471       else if (unformat (i, "vrf %d", &vrf_id))
6472         ;
6473       else if (unformat (i, "ipv6"))
6474         is_ipv6 = 1;
6475       else
6476         break;
6477     }
6478
6479   if (sw_if_index_set == 0)
6480     {
6481       errmsg ("missing interface name or sw_if_index");
6482       return -99;
6483     }
6484
6485   /* Construct the API message */
6486   M (SW_INTERFACE_SET_TABLE, mp);
6487
6488   mp->sw_if_index = ntohl (sw_if_index);
6489   mp->is_ipv6 = is_ipv6;
6490   mp->vrf_id = ntohl (vrf_id);
6491
6492   /* send it... */
6493   S (mp);
6494
6495   /* Wait for a reply... */
6496   W (ret);
6497   return ret;
6498 }
6499
6500 static void vl_api_sw_interface_get_table_reply_t_handler
6501   (vl_api_sw_interface_get_table_reply_t * mp)
6502 {
6503   vat_main_t *vam = &vat_main;
6504
6505   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6506
6507   vam->retval = ntohl (mp->retval);
6508   vam->result_ready = 1;
6509
6510 }
6511
6512 static void vl_api_sw_interface_get_table_reply_t_handler_json
6513   (vl_api_sw_interface_get_table_reply_t * mp)
6514 {
6515   vat_main_t *vam = &vat_main;
6516   vat_json_node_t node;
6517
6518   vat_json_init_object (&node);
6519   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6520   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6521
6522   vat_json_print (vam->ofp, &node);
6523   vat_json_free (&node);
6524
6525   vam->retval = ntohl (mp->retval);
6526   vam->result_ready = 1;
6527 }
6528
6529 static int
6530 api_sw_interface_get_table (vat_main_t * vam)
6531 {
6532   unformat_input_t *i = vam->input;
6533   vl_api_sw_interface_get_table_t *mp;
6534   u32 sw_if_index;
6535   u8 sw_if_index_set = 0;
6536   u8 is_ipv6 = 0;
6537   int ret;
6538
6539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6540     {
6541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6542         sw_if_index_set = 1;
6543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6544         sw_if_index_set = 1;
6545       else if (unformat (i, "ipv6"))
6546         is_ipv6 = 1;
6547       else
6548         break;
6549     }
6550
6551   if (sw_if_index_set == 0)
6552     {
6553       errmsg ("missing interface name or sw_if_index");
6554       return -99;
6555     }
6556
6557   M (SW_INTERFACE_GET_TABLE, mp);
6558   mp->sw_if_index = htonl (sw_if_index);
6559   mp->is_ipv6 = is_ipv6;
6560
6561   S (mp);
6562   W (ret);
6563   return ret;
6564 }
6565
6566 static int
6567 api_sw_interface_set_vpath (vat_main_t * vam)
6568 {
6569   unformat_input_t *i = vam->input;
6570   vl_api_sw_interface_set_vpath_t *mp;
6571   u32 sw_if_index = 0;
6572   u8 sw_if_index_set = 0;
6573   u8 is_enable = 0;
6574   int ret;
6575
6576   /* Parse args required to build the message */
6577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6578     {
6579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6580         sw_if_index_set = 1;
6581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "enable"))
6584         is_enable = 1;
6585       else if (unformat (i, "disable"))
6586         is_enable = 0;
6587       else
6588         break;
6589     }
6590
6591   if (sw_if_index_set == 0)
6592     {
6593       errmsg ("missing interface name or sw_if_index");
6594       return -99;
6595     }
6596
6597   /* Construct the API message */
6598   M (SW_INTERFACE_SET_VPATH, mp);
6599
6600   mp->sw_if_index = ntohl (sw_if_index);
6601   mp->enable = is_enable;
6602
6603   /* send it... */
6604   S (mp);
6605
6606   /* Wait for a reply... */
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6616   u32 sw_if_index = 0;
6617   u8 sw_if_index_set = 0;
6618   u8 is_enable = 1;
6619   u8 is_ipv6 = 0;
6620   int ret;
6621
6622   /* Parse args required to build the message */
6623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6624     {
6625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6628         sw_if_index_set = 1;
6629       else if (unformat (i, "enable"))
6630         is_enable = 1;
6631       else if (unformat (i, "disable"))
6632         is_enable = 0;
6633       else if (unformat (i, "ip4"))
6634         is_ipv6 = 0;
6635       else if (unformat (i, "ip6"))
6636         is_ipv6 = 1;
6637       else
6638         break;
6639     }
6640
6641   if (sw_if_index_set == 0)
6642     {
6643       errmsg ("missing interface name or sw_if_index");
6644       return -99;
6645     }
6646
6647   /* Construct the API message */
6648   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6649
6650   mp->sw_if_index = ntohl (sw_if_index);
6651   mp->enable = is_enable;
6652   mp->is_ipv6 = is_ipv6;
6653
6654   /* send it... */
6655   S (mp);
6656
6657   /* Wait for a reply... */
6658   W (ret);
6659   return ret;
6660 }
6661
6662 static int
6663 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6664 {
6665   unformat_input_t *i = vam->input;
6666   vl_api_sw_interface_set_geneve_bypass_t *mp;
6667   u32 sw_if_index = 0;
6668   u8 sw_if_index_set = 0;
6669   u8 is_enable = 1;
6670   u8 is_ipv6 = 0;
6671   int ret;
6672
6673   /* Parse args required to build the message */
6674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675     {
6676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "enable"))
6681         is_enable = 1;
6682       else if (unformat (i, "disable"))
6683         is_enable = 0;
6684       else if (unformat (i, "ip4"))
6685         is_ipv6 = 0;
6686       else if (unformat (i, "ip6"))
6687         is_ipv6 = 1;
6688       else
6689         break;
6690     }
6691
6692   if (sw_if_index_set == 0)
6693     {
6694       errmsg ("missing interface name or sw_if_index");
6695       return -99;
6696     }
6697
6698   /* Construct the API message */
6699   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6700
6701   mp->sw_if_index = ntohl (sw_if_index);
6702   mp->enable = is_enable;
6703   mp->is_ipv6 = is_ipv6;
6704
6705   /* send it... */
6706   S (mp);
6707
6708   /* Wait for a reply... */
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_sw_interface_set_l2_xconnect_t *mp;
6718   u32 rx_sw_if_index;
6719   u8 rx_sw_if_index_set = 0;
6720   u32 tx_sw_if_index;
6721   u8 tx_sw_if_index_set = 0;
6722   u8 enable = 1;
6723   int ret;
6724
6725   /* Parse args required to build the message */
6726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6727     {
6728       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6729         rx_sw_if_index_set = 1;
6730       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6731         tx_sw_if_index_set = 1;
6732       else if (unformat (i, "rx"))
6733         {
6734           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735             {
6736               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6737                             &rx_sw_if_index))
6738                 rx_sw_if_index_set = 1;
6739             }
6740           else
6741             break;
6742         }
6743       else if (unformat (i, "tx"))
6744         {
6745           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6746             {
6747               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6748                             &tx_sw_if_index))
6749                 tx_sw_if_index_set = 1;
6750             }
6751           else
6752             break;
6753         }
6754       else if (unformat (i, "enable"))
6755         enable = 1;
6756       else if (unformat (i, "disable"))
6757         enable = 0;
6758       else
6759         break;
6760     }
6761
6762   if (rx_sw_if_index_set == 0)
6763     {
6764       errmsg ("missing rx interface name or rx_sw_if_index");
6765       return -99;
6766     }
6767
6768   if (enable && (tx_sw_if_index_set == 0))
6769     {
6770       errmsg ("missing tx interface name or tx_sw_if_index");
6771       return -99;
6772     }
6773
6774   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6775
6776   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6777   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6778   mp->enable = enable;
6779
6780   S (mp);
6781   W (ret);
6782   return ret;
6783 }
6784
6785 static int
6786 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6787 {
6788   unformat_input_t *i = vam->input;
6789   vl_api_sw_interface_set_l2_bridge_t *mp;
6790   u32 rx_sw_if_index;
6791   u8 rx_sw_if_index_set = 0;
6792   u32 bd_id;
6793   u8 bd_id_set = 0;
6794   u8 bvi = 0;
6795   u32 shg = 0;
6796   u8 enable = 1;
6797   int ret;
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6803         rx_sw_if_index_set = 1;
6804       else if (unformat (i, "bd_id %d", &bd_id))
6805         bd_id_set = 1;
6806       else
6807         if (unformat
6808             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6809         rx_sw_if_index_set = 1;
6810       else if (unformat (i, "shg %d", &shg))
6811         ;
6812       else if (unformat (i, "bvi"))
6813         bvi = 1;
6814       else if (unformat (i, "enable"))
6815         enable = 1;
6816       else if (unformat (i, "disable"))
6817         enable = 0;
6818       else
6819         break;
6820     }
6821
6822   if (rx_sw_if_index_set == 0)
6823     {
6824       errmsg ("missing rx interface name or sw_if_index");
6825       return -99;
6826     }
6827
6828   if (enable && (bd_id_set == 0))
6829     {
6830       errmsg ("missing bridge domain");
6831       return -99;
6832     }
6833
6834   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6835
6836   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6837   mp->bd_id = ntohl (bd_id);
6838   mp->shg = (u8) shg;
6839   mp->bvi = bvi;
6840   mp->enable = enable;
6841
6842   S (mp);
6843   W (ret);
6844   return ret;
6845 }
6846
6847 static int
6848 api_bridge_domain_dump (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_bridge_domain_dump_t *mp;
6852   vl_api_control_ping_t *mp_ping;
6853   u32 bd_id = ~0;
6854   int ret;
6855
6856   /* Parse args required to build the message */
6857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6858     {
6859       if (unformat (i, "bd_id %d", &bd_id))
6860         ;
6861       else
6862         break;
6863     }
6864
6865   M (BRIDGE_DOMAIN_DUMP, mp);
6866   mp->bd_id = ntohl (bd_id);
6867   S (mp);
6868
6869   /* Use a control ping for synchronization */
6870   MPING (CONTROL_PING, mp_ping);
6871   S (mp_ping);
6872
6873   W (ret);
6874   return ret;
6875 }
6876
6877 static int
6878 api_bridge_domain_add_del (vat_main_t * vam)
6879 {
6880   unformat_input_t *i = vam->input;
6881   vl_api_bridge_domain_add_del_t *mp;
6882   u32 bd_id = ~0;
6883   u8 is_add = 1;
6884   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6885   u8 *bd_tag = NULL;
6886   u32 mac_age = 0;
6887   int ret;
6888
6889   /* Parse args required to build the message */
6890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891     {
6892       if (unformat (i, "bd_id %d", &bd_id))
6893         ;
6894       else if (unformat (i, "flood %d", &flood))
6895         ;
6896       else if (unformat (i, "uu-flood %d", &uu_flood))
6897         ;
6898       else if (unformat (i, "forward %d", &forward))
6899         ;
6900       else if (unformat (i, "learn %d", &learn))
6901         ;
6902       else if (unformat (i, "arp-term %d", &arp_term))
6903         ;
6904       else if (unformat (i, "mac-age %d", &mac_age))
6905         ;
6906       else if (unformat (i, "bd-tag %s", &bd_tag))
6907         ;
6908       else if (unformat (i, "del"))
6909         {
6910           is_add = 0;
6911           flood = uu_flood = forward = learn = 0;
6912         }
6913       else
6914         break;
6915     }
6916
6917   if (bd_id == ~0)
6918     {
6919       errmsg ("missing bridge domain");
6920       ret = -99;
6921       goto done;
6922     }
6923
6924   if (mac_age > 255)
6925     {
6926       errmsg ("mac age must be less than 256 ");
6927       ret = -99;
6928       goto done;
6929     }
6930
6931   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6932     {
6933       errmsg ("bd-tag cannot be longer than 63");
6934       ret = -99;
6935       goto done;
6936     }
6937
6938   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6939
6940   mp->bd_id = ntohl (bd_id);
6941   mp->flood = flood;
6942   mp->uu_flood = uu_flood;
6943   mp->forward = forward;
6944   mp->learn = learn;
6945   mp->arp_term = arp_term;
6946   mp->is_add = is_add;
6947   mp->mac_age = (u8) mac_age;
6948   if (bd_tag)
6949     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6950
6951   S (mp);
6952   W (ret);
6953
6954 done:
6955   vec_free (bd_tag);
6956   return ret;
6957 }
6958
6959 static int
6960 api_l2fib_flush_bd (vat_main_t * vam)
6961 {
6962   unformat_input_t *i = vam->input;
6963   vl_api_l2fib_flush_bd_t *mp;
6964   u32 bd_id = ~0;
6965   int ret;
6966
6967   /* Parse args required to build the message */
6968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6969     {
6970       if (unformat (i, "bd_id %d", &bd_id));
6971       else
6972         break;
6973     }
6974
6975   if (bd_id == ~0)
6976     {
6977       errmsg ("missing bridge domain");
6978       return -99;
6979     }
6980
6981   M (L2FIB_FLUSH_BD, mp);
6982
6983   mp->bd_id = htonl (bd_id);
6984
6985   S (mp);
6986   W (ret);
6987   return ret;
6988 }
6989
6990 static int
6991 api_l2fib_flush_int (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_l2fib_flush_int_t *mp;
6995   u32 sw_if_index = ~0;
6996   int ret;
6997
6998   /* Parse args required to build the message */
6999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7000     {
7001       if (unformat (i, "sw_if_index %d", &sw_if_index));
7002       else
7003         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7004       else
7005         break;
7006     }
7007
7008   if (sw_if_index == ~0)
7009     {
7010       errmsg ("missing interface name or sw_if_index");
7011       return -99;
7012     }
7013
7014   M (L2FIB_FLUSH_INT, mp);
7015
7016   mp->sw_if_index = ntohl (sw_if_index);
7017
7018   S (mp);
7019   W (ret);
7020   return ret;
7021 }
7022
7023 static int
7024 api_l2fib_add_del (vat_main_t * vam)
7025 {
7026   unformat_input_t *i = vam->input;
7027   vl_api_l2fib_add_del_t *mp;
7028   f64 timeout;
7029   u8 mac[6] = { 0 };
7030   u8 mac_set = 0;
7031   u32 bd_id;
7032   u8 bd_id_set = 0;
7033   u32 sw_if_index = ~0;
7034   u8 sw_if_index_set = 0;
7035   u8 is_add = 1;
7036   u8 static_mac = 0;
7037   u8 filter_mac = 0;
7038   u8 bvi_mac = 0;
7039   int count = 1;
7040   f64 before = 0;
7041   int j;
7042
7043   /* Parse args required to build the message */
7044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7045     {
7046       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7047         mac_set = 1;
7048       else if (unformat (i, "bd_id %d", &bd_id))
7049         bd_id_set = 1;
7050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7051         sw_if_index_set = 1;
7052       else if (unformat (i, "sw_if"))
7053         {
7054           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7055             {
7056               if (unformat
7057                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7058                 sw_if_index_set = 1;
7059             }
7060           else
7061             break;
7062         }
7063       else if (unformat (i, "static"))
7064         static_mac = 1;
7065       else if (unformat (i, "filter"))
7066         {
7067           filter_mac = 1;
7068           static_mac = 1;
7069         }
7070       else if (unformat (i, "bvi"))
7071         {
7072           bvi_mac = 1;
7073           static_mac = 1;
7074         }
7075       else if (unformat (i, "del"))
7076         is_add = 0;
7077       else if (unformat (i, "count %d", &count))
7078         ;
7079       else
7080         break;
7081     }
7082
7083   if (mac_set == 0)
7084     {
7085       errmsg ("missing mac address");
7086       return -99;
7087     }
7088
7089   if (bd_id_set == 0)
7090     {
7091       errmsg ("missing bridge domain");
7092       return -99;
7093     }
7094
7095   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7096     {
7097       errmsg ("missing interface name or sw_if_index");
7098       return -99;
7099     }
7100
7101   if (count > 1)
7102     {
7103       /* Turn on async mode */
7104       vam->async_mode = 1;
7105       vam->async_errors = 0;
7106       before = vat_time_now (vam);
7107     }
7108
7109   for (j = 0; j < count; j++)
7110     {
7111       M (L2FIB_ADD_DEL, mp);
7112
7113       clib_memcpy (mp->mac, mac, 6);
7114       mp->bd_id = ntohl (bd_id);
7115       mp->is_add = is_add;
7116
7117       if (is_add)
7118         {
7119           mp->sw_if_index = ntohl (sw_if_index);
7120           mp->static_mac = static_mac;
7121           mp->filter_mac = filter_mac;
7122           mp->bvi_mac = bvi_mac;
7123         }
7124       increment_mac_address (mac);
7125       /* send it... */
7126       S (mp);
7127     }
7128
7129   if (count > 1)
7130     {
7131       vl_api_control_ping_t *mp_ping;
7132       f64 after;
7133
7134       /* Shut off async mode */
7135       vam->async_mode = 0;
7136
7137       MPING (CONTROL_PING, mp_ping);
7138       S (mp_ping);
7139
7140       timeout = vat_time_now (vam) + 1.0;
7141       while (vat_time_now (vam) < timeout)
7142         if (vam->result_ready == 1)
7143           goto out;
7144       vam->retval = -99;
7145
7146     out:
7147       if (vam->retval == -99)
7148         errmsg ("timeout");
7149
7150       if (vam->async_errors > 0)
7151         {
7152           errmsg ("%d asynchronous errors", vam->async_errors);
7153           vam->retval = -98;
7154         }
7155       vam->async_errors = 0;
7156       after = vat_time_now (vam);
7157
7158       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7159              count, after - before, count / (after - before));
7160     }
7161   else
7162     {
7163       int ret;
7164
7165       /* Wait for a reply... */
7166       W (ret);
7167       return ret;
7168     }
7169   /* Return the good/bad news */
7170   return (vam->retval);
7171 }
7172
7173 static int
7174 api_bridge_domain_set_mac_age (vat_main_t * vam)
7175 {
7176   unformat_input_t *i = vam->input;
7177   vl_api_bridge_domain_set_mac_age_t *mp;
7178   u32 bd_id = ~0;
7179   u32 mac_age = 0;
7180   int ret;
7181
7182   /* Parse args required to build the message */
7183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (i, "bd_id %d", &bd_id));
7186       else if (unformat (i, "mac-age %d", &mac_age));
7187       else
7188         break;
7189     }
7190
7191   if (bd_id == ~0)
7192     {
7193       errmsg ("missing bridge domain");
7194       return -99;
7195     }
7196
7197   if (mac_age > 255)
7198     {
7199       errmsg ("mac age must be less than 256 ");
7200       return -99;
7201     }
7202
7203   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7204
7205   mp->bd_id = htonl (bd_id);
7206   mp->mac_age = (u8) mac_age;
7207
7208   S (mp);
7209   W (ret);
7210   return ret;
7211 }
7212
7213 static int
7214 api_l2_flags (vat_main_t * vam)
7215 {
7216   unformat_input_t *i = vam->input;
7217   vl_api_l2_flags_t *mp;
7218   u32 sw_if_index;
7219   u32 flags = 0;
7220   u8 sw_if_index_set = 0;
7221   u8 is_set = 0;
7222   int ret;
7223
7224   /* Parse args required to build the message */
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "sw_if_index %d", &sw_if_index))
7228         sw_if_index_set = 1;
7229       else if (unformat (i, "sw_if"))
7230         {
7231           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7232             {
7233               if (unformat
7234                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7235                 sw_if_index_set = 1;
7236             }
7237           else
7238             break;
7239         }
7240       else if (unformat (i, "learn"))
7241         flags |= L2_LEARN;
7242       else if (unformat (i, "forward"))
7243         flags |= L2_FWD;
7244       else if (unformat (i, "flood"))
7245         flags |= L2_FLOOD;
7246       else if (unformat (i, "uu-flood"))
7247         flags |= L2_UU_FLOOD;
7248       else if (unformat (i, "arp-term"))
7249         flags |= L2_ARP_TERM;
7250       else if (unformat (i, "off"))
7251         is_set = 0;
7252       else if (unformat (i, "disable"))
7253         is_set = 0;
7254       else
7255         break;
7256     }
7257
7258   if (sw_if_index_set == 0)
7259     {
7260       errmsg ("missing interface name or sw_if_index");
7261       return -99;
7262     }
7263
7264   M (L2_FLAGS, mp);
7265
7266   mp->sw_if_index = ntohl (sw_if_index);
7267   mp->feature_bitmap = ntohl (flags);
7268   mp->is_set = is_set;
7269
7270   S (mp);
7271   W (ret);
7272   return ret;
7273 }
7274
7275 static int
7276 api_bridge_flags (vat_main_t * vam)
7277 {
7278   unformat_input_t *i = vam->input;
7279   vl_api_bridge_flags_t *mp;
7280   u32 bd_id;
7281   u8 bd_id_set = 0;
7282   u8 is_set = 1;
7283   u32 flags = 0;
7284   int ret;
7285
7286   /* Parse args required to build the message */
7287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7288     {
7289       if (unformat (i, "bd_id %d", &bd_id))
7290         bd_id_set = 1;
7291       else if (unformat (i, "learn"))
7292         flags |= L2_LEARN;
7293       else if (unformat (i, "forward"))
7294         flags |= L2_FWD;
7295       else if (unformat (i, "flood"))
7296         flags |= L2_FLOOD;
7297       else if (unformat (i, "uu-flood"))
7298         flags |= L2_UU_FLOOD;
7299       else if (unformat (i, "arp-term"))
7300         flags |= L2_ARP_TERM;
7301       else if (unformat (i, "off"))
7302         is_set = 0;
7303       else if (unformat (i, "disable"))
7304         is_set = 0;
7305       else
7306         break;
7307     }
7308
7309   if (bd_id_set == 0)
7310     {
7311       errmsg ("missing bridge domain");
7312       return -99;
7313     }
7314
7315   M (BRIDGE_FLAGS, mp);
7316
7317   mp->bd_id = ntohl (bd_id);
7318   mp->feature_bitmap = ntohl (flags);
7319   mp->is_set = is_set;
7320
7321   S (mp);
7322   W (ret);
7323   return ret;
7324 }
7325
7326 static int
7327 api_bd_ip_mac_add_del (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_bd_ip_mac_add_del_t *mp;
7331   u32 bd_id;
7332   u8 is_ipv6 = 0;
7333   u8 is_add = 1;
7334   u8 bd_id_set = 0;
7335   u8 ip_set = 0;
7336   u8 mac_set = 0;
7337   ip4_address_t v4addr;
7338   ip6_address_t v6addr;
7339   u8 macaddr[6];
7340   int ret;
7341
7342
7343   /* Parse args required to build the message */
7344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7345     {
7346       if (unformat (i, "bd_id %d", &bd_id))
7347         {
7348           bd_id_set++;
7349         }
7350       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7351         {
7352           ip_set++;
7353         }
7354       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7355         {
7356           ip_set++;
7357           is_ipv6++;
7358         }
7359       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7360         {
7361           mac_set++;
7362         }
7363       else if (unformat (i, "del"))
7364         is_add = 0;
7365       else
7366         break;
7367     }
7368
7369   if (bd_id_set == 0)
7370     {
7371       errmsg ("missing bridge domain");
7372       return -99;
7373     }
7374   else if (ip_set == 0)
7375     {
7376       errmsg ("missing IP address");
7377       return -99;
7378     }
7379   else if (mac_set == 0)
7380     {
7381       errmsg ("missing MAC address");
7382       return -99;
7383     }
7384
7385   M (BD_IP_MAC_ADD_DEL, mp);
7386
7387   mp->bd_id = ntohl (bd_id);
7388   mp->is_ipv6 = is_ipv6;
7389   mp->is_add = is_add;
7390   if (is_ipv6)
7391     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7392   else
7393     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7394   clib_memcpy (mp->mac_address, macaddr, 6);
7395   S (mp);
7396   W (ret);
7397   return ret;
7398 }
7399
7400 static int
7401 api_tap_connect (vat_main_t * vam)
7402 {
7403   unformat_input_t *i = vam->input;
7404   vl_api_tap_connect_t *mp;
7405   u8 mac_address[6];
7406   u8 random_mac = 1;
7407   u8 name_set = 0;
7408   u8 *tap_name;
7409   u8 *tag = 0;
7410   ip4_address_t ip4_address;
7411   u32 ip4_mask_width;
7412   int ip4_address_set = 0;
7413   ip6_address_t ip6_address;
7414   u32 ip6_mask_width;
7415   int ip6_address_set = 0;
7416   int ret;
7417
7418   memset (mac_address, 0, sizeof (mac_address));
7419
7420   /* Parse args required to build the message */
7421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422     {
7423       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7424         {
7425           random_mac = 0;
7426         }
7427       else if (unformat (i, "random-mac"))
7428         random_mac = 1;
7429       else if (unformat (i, "tapname %s", &tap_name))
7430         name_set = 1;
7431       else if (unformat (i, "tag %s", &tag))
7432         ;
7433       else if (unformat (i, "address %U/%d",
7434                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7435         ip4_address_set = 1;
7436       else if (unformat (i, "address %U/%d",
7437                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7438         ip6_address_set = 1;
7439       else
7440         break;
7441     }
7442
7443   if (name_set == 0)
7444     {
7445       errmsg ("missing tap name");
7446       return -99;
7447     }
7448   if (vec_len (tap_name) > 63)
7449     {
7450       errmsg ("tap name too long");
7451       return -99;
7452     }
7453   vec_add1 (tap_name, 0);
7454
7455   if (vec_len (tag) > 63)
7456     {
7457       errmsg ("tag too long");
7458       return -99;
7459     }
7460
7461   /* Construct the API message */
7462   M (TAP_CONNECT, mp);
7463
7464   mp->use_random_mac = random_mac;
7465   clib_memcpy (mp->mac_address, mac_address, 6);
7466   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7467   if (tag)
7468     clib_memcpy (mp->tag, tag, vec_len (tag));
7469
7470   if (ip4_address_set)
7471     {
7472       mp->ip4_address_set = 1;
7473       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7474       mp->ip4_mask_width = ip4_mask_width;
7475     }
7476   if (ip6_address_set)
7477     {
7478       mp->ip6_address_set = 1;
7479       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7480       mp->ip6_mask_width = ip6_mask_width;
7481     }
7482
7483   vec_free (tap_name);
7484   vec_free (tag);
7485
7486   /* send it... */
7487   S (mp);
7488
7489   /* Wait for a reply... */
7490   W (ret);
7491   return ret;
7492 }
7493
7494 static int
7495 api_tap_modify (vat_main_t * vam)
7496 {
7497   unformat_input_t *i = vam->input;
7498   vl_api_tap_modify_t *mp;
7499   u8 mac_address[6];
7500   u8 random_mac = 1;
7501   u8 name_set = 0;
7502   u8 *tap_name;
7503   u32 sw_if_index = ~0;
7504   u8 sw_if_index_set = 0;
7505   int ret;
7506
7507   memset (mac_address, 0, sizeof (mac_address));
7508
7509   /* Parse args required to build the message */
7510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7511     {
7512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7513         sw_if_index_set = 1;
7514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7515         sw_if_index_set = 1;
7516       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7517         {
7518           random_mac = 0;
7519         }
7520       else if (unformat (i, "random-mac"))
7521         random_mac = 1;
7522       else if (unformat (i, "tapname %s", &tap_name))
7523         name_set = 1;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing vpp interface name");
7531       return -99;
7532     }
7533   if (name_set == 0)
7534     {
7535       errmsg ("missing tap name");
7536       return -99;
7537     }
7538   if (vec_len (tap_name) > 63)
7539     {
7540       errmsg ("tap name too long");
7541     }
7542   vec_add1 (tap_name, 0);
7543
7544   /* Construct the API message */
7545   M (TAP_MODIFY, mp);
7546
7547   mp->use_random_mac = random_mac;
7548   mp->sw_if_index = ntohl (sw_if_index);
7549   clib_memcpy (mp->mac_address, mac_address, 6);
7550   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7551   vec_free (tap_name);
7552
7553   /* send it... */
7554   S (mp);
7555
7556   /* Wait for a reply... */
7557   W (ret);
7558   return ret;
7559 }
7560
7561 static int
7562 api_tap_delete (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_tap_delete_t *mp;
7566   u32 sw_if_index = ~0;
7567   u8 sw_if_index_set = 0;
7568   int ret;
7569
7570   /* Parse args required to build the message */
7571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7572     {
7573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7574         sw_if_index_set = 1;
7575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7576         sw_if_index_set = 1;
7577       else
7578         break;
7579     }
7580
7581   if (sw_if_index_set == 0)
7582     {
7583       errmsg ("missing vpp interface name");
7584       return -99;
7585     }
7586
7587   /* Construct the API message */
7588   M (TAP_DELETE, mp);
7589
7590   mp->sw_if_index = ntohl (sw_if_index);
7591
7592   /* send it... */
7593   S (mp);
7594
7595   /* Wait for a reply... */
7596   W (ret);
7597   return ret;
7598 }
7599
7600 static int
7601 api_ip_table_add_del (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_ip_table_add_del_t *mp;
7605   u32 table_id = ~0;
7606   u8 is_ipv6 = 0;
7607   u8 is_add = 1;
7608   int ret = 0;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "ipv6"))
7614         is_ipv6 = 1;
7615       else if (unformat (i, "del"))
7616         is_add = 0;
7617       else if (unformat (i, "add"))
7618         is_add = 1;
7619       else if (unformat (i, "table %d", &table_id))
7620         ;
7621       else
7622         {
7623           clib_warning ("parse error '%U'", format_unformat_error, i);
7624           return -99;
7625         }
7626     }
7627
7628   if (~0 == table_id)
7629     {
7630       errmsg ("missing table-ID");
7631       return -99;
7632     }
7633
7634   /* Construct the API message */
7635   M (IP_TABLE_ADD_DEL, mp);
7636
7637   mp->table_id = ntohl (table_id);
7638   mp->is_ipv6 = is_ipv6;
7639   mp->is_add = is_add;
7640
7641   /* send it... */
7642   S (mp);
7643
7644   /* Wait for a reply... */
7645   W (ret);
7646
7647   return ret;
7648 }
7649
7650 static int
7651 api_ip_add_del_route (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_ip_add_del_route_t *mp;
7655   u32 sw_if_index = ~0, vrf_id = 0;
7656   u8 is_ipv6 = 0;
7657   u8 is_local = 0, is_drop = 0;
7658   u8 is_unreach = 0, is_prohibit = 0;
7659   u8 create_vrf_if_needed = 0;
7660   u8 is_add = 1;
7661   u32 next_hop_weight = 1;
7662   u8 is_multipath = 0;
7663   u8 address_set = 0;
7664   u8 address_length_set = 0;
7665   u32 next_hop_table_id = 0;
7666   u32 resolve_attempts = 0;
7667   u32 dst_address_length = 0;
7668   u8 next_hop_set = 0;
7669   ip4_address_t v4_dst_address, v4_next_hop_address;
7670   ip6_address_t v6_dst_address, v6_next_hop_address;
7671   int count = 1;
7672   int j;
7673   f64 before = 0;
7674   u32 random_add_del = 0;
7675   u32 *random_vector = 0;
7676   uword *random_hash;
7677   u32 random_seed = 0xdeaddabe;
7678   u32 classify_table_index = ~0;
7679   u8 is_classify = 0;
7680   u8 resolve_host = 0, resolve_attached = 0;
7681   mpls_label_t *next_hop_out_label_stack = NULL;
7682   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7683   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7684
7685   /* Parse args required to build the message */
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7689         ;
7690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7691         ;
7692       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7693         {
7694           address_set = 1;
7695           is_ipv6 = 0;
7696         }
7697       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7698         {
7699           address_set = 1;
7700           is_ipv6 = 1;
7701         }
7702       else if (unformat (i, "/%d", &dst_address_length))
7703         {
7704           address_length_set = 1;
7705         }
7706
7707       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7708                                          &v4_next_hop_address))
7709         {
7710           next_hop_set = 1;
7711         }
7712       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7713                                          &v6_next_hop_address))
7714         {
7715           next_hop_set = 1;
7716         }
7717       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7718         ;
7719       else if (unformat (i, "weight %d", &next_hop_weight))
7720         ;
7721       else if (unformat (i, "drop"))
7722         {
7723           is_drop = 1;
7724         }
7725       else if (unformat (i, "null-send-unreach"))
7726         {
7727           is_unreach = 1;
7728         }
7729       else if (unformat (i, "null-send-prohibit"))
7730         {
7731           is_prohibit = 1;
7732         }
7733       else if (unformat (i, "local"))
7734         {
7735           is_local = 1;
7736         }
7737       else if (unformat (i, "classify %d", &classify_table_index))
7738         {
7739           is_classify = 1;
7740         }
7741       else if (unformat (i, "del"))
7742         is_add = 0;
7743       else if (unformat (i, "add"))
7744         is_add = 1;
7745       else if (unformat (i, "resolve-via-host"))
7746         resolve_host = 1;
7747       else if (unformat (i, "resolve-via-attached"))
7748         resolve_attached = 1;
7749       else if (unformat (i, "multipath"))
7750         is_multipath = 1;
7751       else if (unformat (i, "vrf %d", &vrf_id))
7752         ;
7753       else if (unformat (i, "create-vrf"))
7754         create_vrf_if_needed = 1;
7755       else if (unformat (i, "count %d", &count))
7756         ;
7757       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7758         ;
7759       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7760         ;
7761       else if (unformat (i, "out-label %d", &next_hop_out_label))
7762         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7763       else if (unformat (i, "via-label %d", &next_hop_via_label))
7764         ;
7765       else if (unformat (i, "random"))
7766         random_add_del = 1;
7767       else if (unformat (i, "seed %d", &random_seed))
7768         ;
7769       else
7770         {
7771           clib_warning ("parse error '%U'", format_unformat_error, i);
7772           return -99;
7773         }
7774     }
7775
7776   if (!next_hop_set && !is_drop && !is_local &&
7777       !is_classify && !is_unreach && !is_prohibit &&
7778       MPLS_LABEL_INVALID == next_hop_via_label)
7779     {
7780       errmsg
7781         ("next hop / local / drop / unreach / prohibit / classify not set");
7782       return -99;
7783     }
7784
7785   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7786     {
7787       errmsg ("next hop and next-hop via label set");
7788       return -99;
7789     }
7790   if (address_set == 0)
7791     {
7792       errmsg ("missing addresses");
7793       return -99;
7794     }
7795
7796   if (address_length_set == 0)
7797     {
7798       errmsg ("missing address length");
7799       return -99;
7800     }
7801
7802   /* Generate a pile of unique, random routes */
7803   if (random_add_del)
7804     {
7805       u32 this_random_address;
7806       random_hash = hash_create (count, sizeof (uword));
7807
7808       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7809       for (j = 0; j <= count; j++)
7810         {
7811           do
7812             {
7813               this_random_address = random_u32 (&random_seed);
7814               this_random_address =
7815                 clib_host_to_net_u32 (this_random_address);
7816             }
7817           while (hash_get (random_hash, this_random_address));
7818           vec_add1 (random_vector, this_random_address);
7819           hash_set (random_hash, this_random_address, 1);
7820         }
7821       hash_free (random_hash);
7822       v4_dst_address.as_u32 = random_vector[0];
7823     }
7824
7825   if (count > 1)
7826     {
7827       /* Turn on async mode */
7828       vam->async_mode = 1;
7829       vam->async_errors = 0;
7830       before = vat_time_now (vam);
7831     }
7832
7833   for (j = 0; j < count; j++)
7834     {
7835       /* Construct the API message */
7836       M2 (IP_ADD_DEL_ROUTE, mp,
7837           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7838
7839       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7840       mp->table_id = ntohl (vrf_id);
7841       mp->create_vrf_if_needed = create_vrf_if_needed;
7842
7843       mp->is_add = is_add;
7844       mp->is_drop = is_drop;
7845       mp->is_unreach = is_unreach;
7846       mp->is_prohibit = is_prohibit;
7847       mp->is_ipv6 = is_ipv6;
7848       mp->is_local = is_local;
7849       mp->is_classify = is_classify;
7850       mp->is_multipath = is_multipath;
7851       mp->is_resolve_host = resolve_host;
7852       mp->is_resolve_attached = resolve_attached;
7853       mp->next_hop_weight = next_hop_weight;
7854       mp->dst_address_length = dst_address_length;
7855       mp->next_hop_table_id = ntohl (next_hop_table_id);
7856       mp->classify_table_index = ntohl (classify_table_index);
7857       mp->next_hop_via_label = ntohl (next_hop_via_label);
7858       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7859       if (0 != mp->next_hop_n_out_labels)
7860         {
7861           memcpy (mp->next_hop_out_label_stack,
7862                   next_hop_out_label_stack,
7863                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7864           vec_free (next_hop_out_label_stack);
7865         }
7866
7867       if (is_ipv6)
7868         {
7869           clib_memcpy (mp->dst_address, &v6_dst_address,
7870                        sizeof (v6_dst_address));
7871           if (next_hop_set)
7872             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7873                          sizeof (v6_next_hop_address));
7874           increment_v6_address (&v6_dst_address);
7875         }
7876       else
7877         {
7878           clib_memcpy (mp->dst_address, &v4_dst_address,
7879                        sizeof (v4_dst_address));
7880           if (next_hop_set)
7881             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7882                          sizeof (v4_next_hop_address));
7883           if (random_add_del)
7884             v4_dst_address.as_u32 = random_vector[j + 1];
7885           else
7886             increment_v4_address (&v4_dst_address);
7887         }
7888       /* send it... */
7889       S (mp);
7890       /* If we receive SIGTERM, stop now... */
7891       if (vam->do_exit)
7892         break;
7893     }
7894
7895   /* When testing multiple add/del ops, use a control-ping to sync */
7896   if (count > 1)
7897     {
7898       vl_api_control_ping_t *mp_ping;
7899       f64 after;
7900       f64 timeout;
7901
7902       /* Shut off async mode */
7903       vam->async_mode = 0;
7904
7905       MPING (CONTROL_PING, mp_ping);
7906       S (mp_ping);
7907
7908       timeout = vat_time_now (vam) + 1.0;
7909       while (vat_time_now (vam) < timeout)
7910         if (vam->result_ready == 1)
7911           goto out;
7912       vam->retval = -99;
7913
7914     out:
7915       if (vam->retval == -99)
7916         errmsg ("timeout");
7917
7918       if (vam->async_errors > 0)
7919         {
7920           errmsg ("%d asynchronous errors", vam->async_errors);
7921           vam->retval = -98;
7922         }
7923       vam->async_errors = 0;
7924       after = vat_time_now (vam);
7925
7926       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7927       if (j > 0)
7928         count = j;
7929
7930       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7931              count, after - before, count / (after - before));
7932     }
7933   else
7934     {
7935       int ret;
7936
7937       /* Wait for a reply... */
7938       W (ret);
7939       return ret;
7940     }
7941
7942   /* Return the good/bad news */
7943   return (vam->retval);
7944 }
7945
7946 static int
7947 api_ip_mroute_add_del (vat_main_t * vam)
7948 {
7949   unformat_input_t *i = vam->input;
7950   vl_api_ip_mroute_add_del_t *mp;
7951   u32 sw_if_index = ~0, vrf_id = 0;
7952   u8 is_ipv6 = 0;
7953   u8 is_local = 0;
7954   u8 create_vrf_if_needed = 0;
7955   u8 is_add = 1;
7956   u8 address_set = 0;
7957   u32 grp_address_length = 0;
7958   ip4_address_t v4_grp_address, v4_src_address;
7959   ip6_address_t v6_grp_address, v6_src_address;
7960   mfib_itf_flags_t iflags = 0;
7961   mfib_entry_flags_t eflags = 0;
7962   int ret;
7963
7964   /* Parse args required to build the message */
7965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7966     {
7967       if (unformat (i, "sw_if_index %d", &sw_if_index))
7968         ;
7969       else if (unformat (i, "%U %U",
7970                          unformat_ip4_address, &v4_src_address,
7971                          unformat_ip4_address, &v4_grp_address))
7972         {
7973           grp_address_length = 64;
7974           address_set = 1;
7975           is_ipv6 = 0;
7976         }
7977       else if (unformat (i, "%U %U",
7978                          unformat_ip6_address, &v6_src_address,
7979                          unformat_ip6_address, &v6_grp_address))
7980         {
7981           grp_address_length = 256;
7982           address_set = 1;
7983           is_ipv6 = 1;
7984         }
7985       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7986         {
7987           memset (&v4_src_address, 0, sizeof (v4_src_address));
7988           grp_address_length = 32;
7989           address_set = 1;
7990           is_ipv6 = 0;
7991         }
7992       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7993         {
7994           memset (&v6_src_address, 0, sizeof (v6_src_address));
7995           grp_address_length = 128;
7996           address_set = 1;
7997           is_ipv6 = 1;
7998         }
7999       else if (unformat (i, "/%d", &grp_address_length))
8000         ;
8001       else if (unformat (i, "local"))
8002         {
8003           is_local = 1;
8004         }
8005       else if (unformat (i, "del"))
8006         is_add = 0;
8007       else if (unformat (i, "add"))
8008         is_add = 1;
8009       else if (unformat (i, "vrf %d", &vrf_id))
8010         ;
8011       else if (unformat (i, "create-vrf"))
8012         create_vrf_if_needed = 1;
8013       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8014         ;
8015       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8016         ;
8017       else
8018         {
8019           clib_warning ("parse error '%U'", format_unformat_error, i);
8020           return -99;
8021         }
8022     }
8023
8024   if (address_set == 0)
8025     {
8026       errmsg ("missing addresses\n");
8027       return -99;
8028     }
8029
8030   /* Construct the API message */
8031   M (IP_MROUTE_ADD_DEL, mp);
8032
8033   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8034   mp->table_id = ntohl (vrf_id);
8035   mp->create_vrf_if_needed = create_vrf_if_needed;
8036
8037   mp->is_add = is_add;
8038   mp->is_ipv6 = is_ipv6;
8039   mp->is_local = is_local;
8040   mp->itf_flags = ntohl (iflags);
8041   mp->entry_flags = ntohl (eflags);
8042   mp->grp_address_length = grp_address_length;
8043   mp->grp_address_length = ntohs (mp->grp_address_length);
8044
8045   if (is_ipv6)
8046     {
8047       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8048       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8049     }
8050   else
8051     {
8052       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8053       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8054
8055     }
8056
8057   /* send it... */
8058   S (mp);
8059   /* Wait for a reply... */
8060   W (ret);
8061   return ret;
8062 }
8063
8064 static int
8065 api_mpls_table_add_del (vat_main_t * vam)
8066 {
8067   unformat_input_t *i = vam->input;
8068   vl_api_mpls_table_add_del_t *mp;
8069   u32 table_id = ~0;
8070   u8 is_add = 1;
8071   int ret = 0;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "table %d", &table_id))
8077         ;
8078       else if (unformat (i, "del"))
8079         is_add = 0;
8080       else if (unformat (i, "add"))
8081         is_add = 1;
8082       else
8083         {
8084           clib_warning ("parse error '%U'", format_unformat_error, i);
8085           return -99;
8086         }
8087     }
8088
8089   if (~0 == table_id)
8090     {
8091       errmsg ("missing table-ID");
8092       return -99;
8093     }
8094
8095   /* Construct the API message */
8096   M (MPLS_TABLE_ADD_DEL, mp);
8097
8098   mp->mt_table_id = ntohl (table_id);
8099   mp->mt_is_add = is_add;
8100
8101   /* send it... */
8102   S (mp);
8103
8104   /* Wait for a reply... */
8105   W (ret);
8106
8107   return ret;
8108 }
8109
8110 static int
8111 api_mpls_route_add_del (vat_main_t * vam)
8112 {
8113   unformat_input_t *i = vam->input;
8114   vl_api_mpls_route_add_del_t *mp;
8115   u32 sw_if_index = ~0, table_id = 0;
8116   u8 create_table_if_needed = 0;
8117   u8 is_add = 1;
8118   u32 next_hop_weight = 1;
8119   u8 is_multipath = 0;
8120   u32 next_hop_table_id = 0;
8121   u8 next_hop_set = 0;
8122   ip4_address_t v4_next_hop_address = {
8123     .as_u32 = 0,
8124   };
8125   ip6_address_t v6_next_hop_address = { {0} };
8126   int count = 1;
8127   int j;
8128   f64 before = 0;
8129   u32 classify_table_index = ~0;
8130   u8 is_classify = 0;
8131   u8 resolve_host = 0, resolve_attached = 0;
8132   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8133   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8134   mpls_label_t *next_hop_out_label_stack = NULL;
8135   mpls_label_t local_label = MPLS_LABEL_INVALID;
8136   u8 is_eos = 0;
8137   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8138
8139   /* Parse args required to build the message */
8140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8143         ;
8144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8145         ;
8146       else if (unformat (i, "%d", &local_label))
8147         ;
8148       else if (unformat (i, "eos"))
8149         is_eos = 1;
8150       else if (unformat (i, "non-eos"))
8151         is_eos = 0;
8152       else if (unformat (i, "via %U", unformat_ip4_address,
8153                          &v4_next_hop_address))
8154         {
8155           next_hop_set = 1;
8156           next_hop_proto = DPO_PROTO_IP4;
8157         }
8158       else if (unformat (i, "via %U", unformat_ip6_address,
8159                          &v6_next_hop_address))
8160         {
8161           next_hop_set = 1;
8162           next_hop_proto = DPO_PROTO_IP6;
8163         }
8164       else if (unformat (i, "weight %d", &next_hop_weight))
8165         ;
8166       else if (unformat (i, "create-table"))
8167         create_table_if_needed = 1;
8168       else if (unformat (i, "classify %d", &classify_table_index))
8169         {
8170           is_classify = 1;
8171         }
8172       else if (unformat (i, "del"))
8173         is_add = 0;
8174       else if (unformat (i, "add"))
8175         is_add = 1;
8176       else if (unformat (i, "resolve-via-host"))
8177         resolve_host = 1;
8178       else if (unformat (i, "resolve-via-attached"))
8179         resolve_attached = 1;
8180       else if (unformat (i, "multipath"))
8181         is_multipath = 1;
8182       else if (unformat (i, "count %d", &count))
8183         ;
8184       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8185         {
8186           next_hop_set = 1;
8187           next_hop_proto = DPO_PROTO_IP4;
8188         }
8189       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8190         {
8191           next_hop_set = 1;
8192           next_hop_proto = DPO_PROTO_IP6;
8193         }
8194       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8195         ;
8196       else if (unformat (i, "via-label %d", &next_hop_via_label))
8197         ;
8198       else if (unformat (i, "out-label %d", &next_hop_out_label))
8199         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8200       else
8201         {
8202           clib_warning ("parse error '%U'", format_unformat_error, i);
8203           return -99;
8204         }
8205     }
8206
8207   if (!next_hop_set && !is_classify)
8208     {
8209       errmsg ("next hop / classify not set");
8210       return -99;
8211     }
8212
8213   if (MPLS_LABEL_INVALID == local_label)
8214     {
8215       errmsg ("missing label");
8216       return -99;
8217     }
8218
8219   if (count > 1)
8220     {
8221       /* Turn on async mode */
8222       vam->async_mode = 1;
8223       vam->async_errors = 0;
8224       before = vat_time_now (vam);
8225     }
8226
8227   for (j = 0; j < count; j++)
8228     {
8229       /* Construct the API message */
8230       M2 (MPLS_ROUTE_ADD_DEL, mp,
8231           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8232
8233       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8234       mp->mr_table_id = ntohl (table_id);
8235       mp->mr_create_table_if_needed = create_table_if_needed;
8236
8237       mp->mr_is_add = is_add;
8238       mp->mr_next_hop_proto = next_hop_proto;
8239       mp->mr_is_classify = is_classify;
8240       mp->mr_is_multipath = is_multipath;
8241       mp->mr_is_resolve_host = resolve_host;
8242       mp->mr_is_resolve_attached = resolve_attached;
8243       mp->mr_next_hop_weight = next_hop_weight;
8244       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8245       mp->mr_classify_table_index = ntohl (classify_table_index);
8246       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8247       mp->mr_label = ntohl (local_label);
8248       mp->mr_eos = is_eos;
8249
8250       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8251       if (0 != mp->mr_next_hop_n_out_labels)
8252         {
8253           memcpy (mp->mr_next_hop_out_label_stack,
8254                   next_hop_out_label_stack,
8255                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8256           vec_free (next_hop_out_label_stack);
8257         }
8258
8259       if (next_hop_set)
8260         {
8261           if (DPO_PROTO_IP4 == next_hop_proto)
8262             {
8263               clib_memcpy (mp->mr_next_hop,
8264                            &v4_next_hop_address,
8265                            sizeof (v4_next_hop_address));
8266             }
8267           else if (DPO_PROTO_IP6 == next_hop_proto)
8268
8269             {
8270               clib_memcpy (mp->mr_next_hop,
8271                            &v6_next_hop_address,
8272                            sizeof (v6_next_hop_address));
8273             }
8274         }
8275       local_label++;
8276
8277       /* send it... */
8278       S (mp);
8279       /* If we receive SIGTERM, stop now... */
8280       if (vam->do_exit)
8281         break;
8282     }
8283
8284   /* When testing multiple add/del ops, use a control-ping to sync */
8285   if (count > 1)
8286     {
8287       vl_api_control_ping_t *mp_ping;
8288       f64 after;
8289       f64 timeout;
8290
8291       /* Shut off async mode */
8292       vam->async_mode = 0;
8293
8294       MPING (CONTROL_PING, mp_ping);
8295       S (mp_ping);
8296
8297       timeout = vat_time_now (vam) + 1.0;
8298       while (vat_time_now (vam) < timeout)
8299         if (vam->result_ready == 1)
8300           goto out;
8301       vam->retval = -99;
8302
8303     out:
8304       if (vam->retval == -99)
8305         errmsg ("timeout");
8306
8307       if (vam->async_errors > 0)
8308         {
8309           errmsg ("%d asynchronous errors", vam->async_errors);
8310           vam->retval = -98;
8311         }
8312       vam->async_errors = 0;
8313       after = vat_time_now (vam);
8314
8315       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8316       if (j > 0)
8317         count = j;
8318
8319       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8320              count, after - before, count / (after - before));
8321     }
8322   else
8323     {
8324       int ret;
8325
8326       /* Wait for a reply... */
8327       W (ret);
8328       return ret;
8329     }
8330
8331   /* Return the good/bad news */
8332   return (vam->retval);
8333 }
8334
8335 static int
8336 api_mpls_ip_bind_unbind (vat_main_t * vam)
8337 {
8338   unformat_input_t *i = vam->input;
8339   vl_api_mpls_ip_bind_unbind_t *mp;
8340   u32 ip_table_id = 0;
8341   u8 create_table_if_needed = 0;
8342   u8 is_bind = 1;
8343   u8 is_ip4 = 1;
8344   ip4_address_t v4_address;
8345   ip6_address_t v6_address;
8346   u32 address_length;
8347   u8 address_set = 0;
8348   mpls_label_t local_label = MPLS_LABEL_INVALID;
8349   int ret;
8350
8351   /* Parse args required to build the message */
8352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8353     {
8354       if (unformat (i, "%U/%d", unformat_ip4_address,
8355                     &v4_address, &address_length))
8356         {
8357           is_ip4 = 1;
8358           address_set = 1;
8359         }
8360       else if (unformat (i, "%U/%d", unformat_ip6_address,
8361                          &v6_address, &address_length))
8362         {
8363           is_ip4 = 0;
8364           address_set = 1;
8365         }
8366       else if (unformat (i, "%d", &local_label))
8367         ;
8368       else if (unformat (i, "create-table"))
8369         create_table_if_needed = 1;
8370       else if (unformat (i, "table-id %d", &ip_table_id))
8371         ;
8372       else if (unformat (i, "unbind"))
8373         is_bind = 0;
8374       else if (unformat (i, "bind"))
8375         is_bind = 1;
8376       else
8377         {
8378           clib_warning ("parse error '%U'", format_unformat_error, i);
8379           return -99;
8380         }
8381     }
8382
8383   if (!address_set)
8384     {
8385       errmsg ("IP addres not set");
8386       return -99;
8387     }
8388
8389   if (MPLS_LABEL_INVALID == local_label)
8390     {
8391       errmsg ("missing label");
8392       return -99;
8393     }
8394
8395   /* Construct the API message */
8396   M (MPLS_IP_BIND_UNBIND, mp);
8397
8398   mp->mb_create_table_if_needed = create_table_if_needed;
8399   mp->mb_is_bind = is_bind;
8400   mp->mb_is_ip4 = is_ip4;
8401   mp->mb_ip_table_id = ntohl (ip_table_id);
8402   mp->mb_mpls_table_id = 0;
8403   mp->mb_label = ntohl (local_label);
8404   mp->mb_address_length = address_length;
8405
8406   if (is_ip4)
8407     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8408   else
8409     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8410
8411   /* send it... */
8412   S (mp);
8413
8414   /* Wait for a reply... */
8415   W (ret);
8416   return ret;
8417 }
8418
8419 static int
8420 api_proxy_arp_add_del (vat_main_t * vam)
8421 {
8422   unformat_input_t *i = vam->input;
8423   vl_api_proxy_arp_add_del_t *mp;
8424   u32 vrf_id = 0;
8425   u8 is_add = 1;
8426   ip4_address_t lo, hi;
8427   u8 range_set = 0;
8428   int ret;
8429
8430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8431     {
8432       if (unformat (i, "vrf %d", &vrf_id))
8433         ;
8434       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8435                          unformat_ip4_address, &hi))
8436         range_set = 1;
8437       else if (unformat (i, "del"))
8438         is_add = 0;
8439       else
8440         {
8441           clib_warning ("parse error '%U'", format_unformat_error, i);
8442           return -99;
8443         }
8444     }
8445
8446   if (range_set == 0)
8447     {
8448       errmsg ("address range not set");
8449       return -99;
8450     }
8451
8452   M (PROXY_ARP_ADD_DEL, mp);
8453
8454   mp->vrf_id = ntohl (vrf_id);
8455   mp->is_add = is_add;
8456   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8457   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8458
8459   S (mp);
8460   W (ret);
8461   return ret;
8462 }
8463
8464 static int
8465 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8466 {
8467   unformat_input_t *i = vam->input;
8468   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8469   u32 sw_if_index;
8470   u8 enable = 1;
8471   u8 sw_if_index_set = 0;
8472   int ret;
8473
8474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8475     {
8476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8477         sw_if_index_set = 1;
8478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8479         sw_if_index_set = 1;
8480       else if (unformat (i, "enable"))
8481         enable = 1;
8482       else if (unformat (i, "disable"))
8483         enable = 0;
8484       else
8485         {
8486           clib_warning ("parse error '%U'", format_unformat_error, i);
8487           return -99;
8488         }
8489     }
8490
8491   if (sw_if_index_set == 0)
8492     {
8493       errmsg ("missing interface name or sw_if_index");
8494       return -99;
8495     }
8496
8497   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8498
8499   mp->sw_if_index = ntohl (sw_if_index);
8500   mp->enable_disable = enable;
8501
8502   S (mp);
8503   W (ret);
8504   return ret;
8505 }
8506
8507 static int
8508 api_mpls_tunnel_add_del (vat_main_t * vam)
8509 {
8510   unformat_input_t *i = vam->input;
8511   vl_api_mpls_tunnel_add_del_t *mp;
8512
8513   u8 is_add = 1;
8514   u8 l2_only = 0;
8515   u32 sw_if_index = ~0;
8516   u32 next_hop_sw_if_index = ~0;
8517   u32 next_hop_proto_is_ip4 = 1;
8518
8519   u32 next_hop_table_id = 0;
8520   ip4_address_t v4_next_hop_address = {
8521     .as_u32 = 0,
8522   };
8523   ip6_address_t v6_next_hop_address = { {0} };
8524   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8525   int ret;
8526
8527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8528     {
8529       if (unformat (i, "add"))
8530         is_add = 1;
8531       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8532         is_add = 0;
8533       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8534         ;
8535       else if (unformat (i, "via %U",
8536                          unformat_ip4_address, &v4_next_hop_address))
8537         {
8538           next_hop_proto_is_ip4 = 1;
8539         }
8540       else if (unformat (i, "via %U",
8541                          unformat_ip6_address, &v6_next_hop_address))
8542         {
8543           next_hop_proto_is_ip4 = 0;
8544         }
8545       else if (unformat (i, "l2-only"))
8546         l2_only = 1;
8547       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8548         ;
8549       else if (unformat (i, "out-label %d", &next_hop_out_label))
8550         vec_add1 (labels, ntohl (next_hop_out_label));
8551       else
8552         {
8553           clib_warning ("parse error '%U'", format_unformat_error, i);
8554           return -99;
8555         }
8556     }
8557
8558   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8559
8560   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8561   mp->mt_sw_if_index = ntohl (sw_if_index);
8562   mp->mt_is_add = is_add;
8563   mp->mt_l2_only = l2_only;
8564   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8565   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8566
8567   mp->mt_next_hop_n_out_labels = vec_len (labels);
8568
8569   if (0 != mp->mt_next_hop_n_out_labels)
8570     {
8571       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8572                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8573       vec_free (labels);
8574     }
8575
8576   if (next_hop_proto_is_ip4)
8577     {
8578       clib_memcpy (mp->mt_next_hop,
8579                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8580     }
8581   else
8582     {
8583       clib_memcpy (mp->mt_next_hop,
8584                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8585     }
8586
8587   S (mp);
8588   W (ret);
8589   return ret;
8590 }
8591
8592 static int
8593 api_sw_interface_set_unnumbered (vat_main_t * vam)
8594 {
8595   unformat_input_t *i = vam->input;
8596   vl_api_sw_interface_set_unnumbered_t *mp;
8597   u32 sw_if_index;
8598   u32 unnum_sw_index = ~0;
8599   u8 is_add = 1;
8600   u8 sw_if_index_set = 0;
8601   int ret;
8602
8603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8604     {
8605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8606         sw_if_index_set = 1;
8607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8610         ;
8611       else if (unformat (i, "del"))
8612         is_add = 0;
8613       else
8614         {
8615           clib_warning ("parse error '%U'", format_unformat_error, i);
8616           return -99;
8617         }
8618     }
8619
8620   if (sw_if_index_set == 0)
8621     {
8622       errmsg ("missing interface name or sw_if_index");
8623       return -99;
8624     }
8625
8626   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8627
8628   mp->sw_if_index = ntohl (sw_if_index);
8629   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8630   mp->is_add = is_add;
8631
8632   S (mp);
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_ip_neighbor_add_del (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_ip_neighbor_add_del_t *mp;
8642   u32 sw_if_index;
8643   u8 sw_if_index_set = 0;
8644   u8 is_add = 1;
8645   u8 is_static = 0;
8646   u8 is_no_fib_entry = 0;
8647   u8 mac_address[6];
8648   u8 mac_set = 0;
8649   u8 v4_address_set = 0;
8650   u8 v6_address_set = 0;
8651   ip4_address_t v4address;
8652   ip6_address_t v6address;
8653   int ret;
8654
8655   memset (mac_address, 0, sizeof (mac_address));
8656
8657   /* Parse args required to build the message */
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8661         {
8662           mac_set = 1;
8663         }
8664       else if (unformat (i, "del"))
8665         is_add = 0;
8666       else
8667         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8668         sw_if_index_set = 1;
8669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8670         sw_if_index_set = 1;
8671       else if (unformat (i, "is_static"))
8672         is_static = 1;
8673       else if (unformat (i, "no-fib-entry"))
8674         is_no_fib_entry = 1;
8675       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8676         v4_address_set = 1;
8677       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8678         v6_address_set = 1;
8679       else
8680         {
8681           clib_warning ("parse error '%U'", format_unformat_error, i);
8682           return -99;
8683         }
8684     }
8685
8686   if (sw_if_index_set == 0)
8687     {
8688       errmsg ("missing interface name or sw_if_index");
8689       return -99;
8690     }
8691   if (v4_address_set && v6_address_set)
8692     {
8693       errmsg ("both v4 and v6 addresses set");
8694       return -99;
8695     }
8696   if (!v4_address_set && !v6_address_set)
8697     {
8698       errmsg ("no address set");
8699       return -99;
8700     }
8701
8702   /* Construct the API message */
8703   M (IP_NEIGHBOR_ADD_DEL, mp);
8704
8705   mp->sw_if_index = ntohl (sw_if_index);
8706   mp->is_add = is_add;
8707   mp->is_static = is_static;
8708   mp->is_no_adj_fib = is_no_fib_entry;
8709   if (mac_set)
8710     clib_memcpy (mp->mac_address, mac_address, 6);
8711   if (v6_address_set)
8712     {
8713       mp->is_ipv6 = 1;
8714       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8715     }
8716   else
8717     {
8718       /* mp->is_ipv6 = 0; via memset in M macro above */
8719       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8720     }
8721
8722   /* send it... */
8723   S (mp);
8724
8725   /* Wait for a reply, return good/bad news  */
8726   W (ret);
8727   return ret;
8728 }
8729
8730 static int
8731 api_reset_vrf (vat_main_t * vam)
8732 {
8733   unformat_input_t *i = vam->input;
8734   vl_api_reset_vrf_t *mp;
8735   u32 vrf_id = 0;
8736   u8 is_ipv6 = 0;
8737   u8 vrf_id_set = 0;
8738   int ret;
8739
8740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8741     {
8742       if (unformat (i, "vrf %d", &vrf_id))
8743         vrf_id_set = 1;
8744       else if (unformat (i, "ipv6"))
8745         is_ipv6 = 1;
8746       else
8747         {
8748           clib_warning ("parse error '%U'", format_unformat_error, i);
8749           return -99;
8750         }
8751     }
8752
8753   if (vrf_id_set == 0)
8754     {
8755       errmsg ("missing vrf id");
8756       return -99;
8757     }
8758
8759   M (RESET_VRF, mp);
8760
8761   mp->vrf_id = ntohl (vrf_id);
8762   mp->is_ipv6 = is_ipv6;
8763
8764   S (mp);
8765   W (ret);
8766   return ret;
8767 }
8768
8769 static int
8770 api_create_vlan_subif (vat_main_t * vam)
8771 {
8772   unformat_input_t *i = vam->input;
8773   vl_api_create_vlan_subif_t *mp;
8774   u32 sw_if_index;
8775   u8 sw_if_index_set = 0;
8776   u32 vlan_id;
8777   u8 vlan_id_set = 0;
8778   int ret;
8779
8780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781     {
8782       if (unformat (i, "sw_if_index %d", &sw_if_index))
8783         sw_if_index_set = 1;
8784       else
8785         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8786         sw_if_index_set = 1;
8787       else if (unformat (i, "vlan %d", &vlan_id))
8788         vlan_id_set = 1;
8789       else
8790         {
8791           clib_warning ("parse error '%U'", format_unformat_error, i);
8792           return -99;
8793         }
8794     }
8795
8796   if (sw_if_index_set == 0)
8797     {
8798       errmsg ("missing interface name or sw_if_index");
8799       return -99;
8800     }
8801
8802   if (vlan_id_set == 0)
8803     {
8804       errmsg ("missing vlan_id");
8805       return -99;
8806     }
8807   M (CREATE_VLAN_SUBIF, mp);
8808
8809   mp->sw_if_index = ntohl (sw_if_index);
8810   mp->vlan_id = ntohl (vlan_id);
8811
8812   S (mp);
8813   W (ret);
8814   return ret;
8815 }
8816
8817 #define foreach_create_subif_bit                \
8818 _(no_tags)                                      \
8819 _(one_tag)                                      \
8820 _(two_tags)                                     \
8821 _(dot1ad)                                       \
8822 _(exact_match)                                  \
8823 _(default_sub)                                  \
8824 _(outer_vlan_id_any)                            \
8825 _(inner_vlan_id_any)
8826
8827 static int
8828 api_create_subif (vat_main_t * vam)
8829 {
8830   unformat_input_t *i = vam->input;
8831   vl_api_create_subif_t *mp;
8832   u32 sw_if_index;
8833   u8 sw_if_index_set = 0;
8834   u32 sub_id;
8835   u8 sub_id_set = 0;
8836   u32 no_tags = 0;
8837   u32 one_tag = 0;
8838   u32 two_tags = 0;
8839   u32 dot1ad = 0;
8840   u32 exact_match = 0;
8841   u32 default_sub = 0;
8842   u32 outer_vlan_id_any = 0;
8843   u32 inner_vlan_id_any = 0;
8844   u32 tmp;
8845   u16 outer_vlan_id = 0;
8846   u16 inner_vlan_id = 0;
8847   int ret;
8848
8849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8850     {
8851       if (unformat (i, "sw_if_index %d", &sw_if_index))
8852         sw_if_index_set = 1;
8853       else
8854         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8855         sw_if_index_set = 1;
8856       else if (unformat (i, "sub_id %d", &sub_id))
8857         sub_id_set = 1;
8858       else if (unformat (i, "outer_vlan_id %d", &tmp))
8859         outer_vlan_id = tmp;
8860       else if (unformat (i, "inner_vlan_id %d", &tmp))
8861         inner_vlan_id = tmp;
8862
8863 #define _(a) else if (unformat (i, #a)) a = 1 ;
8864       foreach_create_subif_bit
8865 #undef _
8866         else
8867         {
8868           clib_warning ("parse error '%U'", format_unformat_error, i);
8869           return -99;
8870         }
8871     }
8872
8873   if (sw_if_index_set == 0)
8874     {
8875       errmsg ("missing interface name or sw_if_index");
8876       return -99;
8877     }
8878
8879   if (sub_id_set == 0)
8880     {
8881       errmsg ("missing sub_id");
8882       return -99;
8883     }
8884   M (CREATE_SUBIF, mp);
8885
8886   mp->sw_if_index = ntohl (sw_if_index);
8887   mp->sub_id = ntohl (sub_id);
8888
8889 #define _(a) mp->a = a;
8890   foreach_create_subif_bit;
8891 #undef _
8892
8893   mp->outer_vlan_id = ntohs (outer_vlan_id);
8894   mp->inner_vlan_id = ntohs (inner_vlan_id);
8895
8896   S (mp);
8897   W (ret);
8898   return ret;
8899 }
8900
8901 static int
8902 api_oam_add_del (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   vl_api_oam_add_del_t *mp;
8906   u32 vrf_id = 0;
8907   u8 is_add = 1;
8908   ip4_address_t src, dst;
8909   u8 src_set = 0;
8910   u8 dst_set = 0;
8911   int ret;
8912
8913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8914     {
8915       if (unformat (i, "vrf %d", &vrf_id))
8916         ;
8917       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8918         src_set = 1;
8919       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8920         dst_set = 1;
8921       else if (unformat (i, "del"))
8922         is_add = 0;
8923       else
8924         {
8925           clib_warning ("parse error '%U'", format_unformat_error, i);
8926           return -99;
8927         }
8928     }
8929
8930   if (src_set == 0)
8931     {
8932       errmsg ("missing src addr");
8933       return -99;
8934     }
8935
8936   if (dst_set == 0)
8937     {
8938       errmsg ("missing dst addr");
8939       return -99;
8940     }
8941
8942   M (OAM_ADD_DEL, mp);
8943
8944   mp->vrf_id = ntohl (vrf_id);
8945   mp->is_add = is_add;
8946   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8947   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8948
8949   S (mp);
8950   W (ret);
8951   return ret;
8952 }
8953
8954 static int
8955 api_reset_fib (vat_main_t * vam)
8956 {
8957   unformat_input_t *i = vam->input;
8958   vl_api_reset_fib_t *mp;
8959   u32 vrf_id = 0;
8960   u8 is_ipv6 = 0;
8961   u8 vrf_id_set = 0;
8962
8963   int ret;
8964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8965     {
8966       if (unformat (i, "vrf %d", &vrf_id))
8967         vrf_id_set = 1;
8968       else if (unformat (i, "ipv6"))
8969         is_ipv6 = 1;
8970       else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (vrf_id_set == 0)
8978     {
8979       errmsg ("missing vrf id");
8980       return -99;
8981     }
8982
8983   M (RESET_FIB, mp);
8984
8985   mp->vrf_id = ntohl (vrf_id);
8986   mp->is_ipv6 = is_ipv6;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_dhcp_proxy_config (vat_main_t * vam)
8995 {
8996   unformat_input_t *i = vam->input;
8997   vl_api_dhcp_proxy_config_t *mp;
8998   u32 rx_vrf_id = 0;
8999   u32 server_vrf_id = 0;
9000   u8 is_add = 1;
9001   u8 v4_address_set = 0;
9002   u8 v6_address_set = 0;
9003   ip4_address_t v4address;
9004   ip6_address_t v6address;
9005   u8 v4_src_address_set = 0;
9006   u8 v6_src_address_set = 0;
9007   ip4_address_t v4srcaddress;
9008   ip6_address_t v6srcaddress;
9009   int ret;
9010
9011   /* Parse args required to build the message */
9012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (i, "del"))
9015         is_add = 0;
9016       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9017         ;
9018       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9019         ;
9020       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9021         v4_address_set = 1;
9022       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9023         v6_address_set = 1;
9024       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9025         v4_src_address_set = 1;
9026       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9027         v6_src_address_set = 1;
9028       else
9029         break;
9030     }
9031
9032   if (v4_address_set && v6_address_set)
9033     {
9034       errmsg ("both v4 and v6 server addresses set");
9035       return -99;
9036     }
9037   if (!v4_address_set && !v6_address_set)
9038     {
9039       errmsg ("no server addresses set");
9040       return -99;
9041     }
9042
9043   if (v4_src_address_set && v6_src_address_set)
9044     {
9045       errmsg ("both v4 and v6  src addresses set");
9046       return -99;
9047     }
9048   if (!v4_src_address_set && !v6_src_address_set)
9049     {
9050       errmsg ("no src addresses set");
9051       return -99;
9052     }
9053
9054   if (!(v4_src_address_set && v4_address_set) &&
9055       !(v6_src_address_set && v6_address_set))
9056     {
9057       errmsg ("no matching server and src addresses set");
9058       return -99;
9059     }
9060
9061   /* Construct the API message */
9062   M (DHCP_PROXY_CONFIG, mp);
9063
9064   mp->is_add = is_add;
9065   mp->rx_vrf_id = ntohl (rx_vrf_id);
9066   mp->server_vrf_id = ntohl (server_vrf_id);
9067   if (v6_address_set)
9068     {
9069       mp->is_ipv6 = 1;
9070       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9071       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9072     }
9073   else
9074     {
9075       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9076       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9077     }
9078
9079   /* send it... */
9080   S (mp);
9081
9082   /* Wait for a reply, return good/bad news  */
9083   W (ret);
9084   return ret;
9085 }
9086
9087 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9088 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9089
9090 static void
9091 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9092 {
9093   vat_main_t *vam = &vat_main;
9094   u32 i, count = mp->count;
9095   vl_api_dhcp_server_t *s;
9096
9097   if (mp->is_ipv6)
9098     print (vam->ofp,
9099            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9100            ntohl (mp->rx_vrf_id),
9101            format_ip6_address, mp->dhcp_src_address,
9102            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9103   else
9104     print (vam->ofp,
9105            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9106            ntohl (mp->rx_vrf_id),
9107            format_ip4_address, mp->dhcp_src_address,
9108            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9109
9110   for (i = 0; i < count; i++)
9111     {
9112       s = &mp->servers[i];
9113
9114       if (mp->is_ipv6)
9115         print (vam->ofp,
9116                " Server Table-ID %d, Server Address %U",
9117                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9118       else
9119         print (vam->ofp,
9120                " Server Table-ID %d, Server Address %U",
9121                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9122     }
9123 }
9124
9125 static void vl_api_dhcp_proxy_details_t_handler_json
9126   (vl_api_dhcp_proxy_details_t * mp)
9127 {
9128   vat_main_t *vam = &vat_main;
9129   vat_json_node_t *node = NULL;
9130   u32 i, count = mp->count;
9131   struct in_addr ip4;
9132   struct in6_addr ip6;
9133   vl_api_dhcp_server_t *s;
9134
9135   if (VAT_JSON_ARRAY != vam->json_tree.type)
9136     {
9137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9138       vat_json_init_array (&vam->json_tree);
9139     }
9140   node = vat_json_array_add (&vam->json_tree);
9141
9142   vat_json_init_object (node);
9143   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9144   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9145   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9146
9147   if (mp->is_ipv6)
9148     {
9149       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9150       vat_json_object_add_ip6 (node, "src_address", ip6);
9151     }
9152   else
9153     {
9154       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9155       vat_json_object_add_ip4 (node, "src_address", ip4);
9156     }
9157
9158   for (i = 0; i < count; i++)
9159     {
9160       s = &mp->servers[i];
9161
9162       vat_json_object_add_uint (node, "server-table-id",
9163                                 ntohl (s->server_vrf_id));
9164
9165       if (mp->is_ipv6)
9166         {
9167           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9168           vat_json_object_add_ip4 (node, "src_address", ip4);
9169         }
9170       else
9171         {
9172           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9173           vat_json_object_add_ip6 (node, "server_address", ip6);
9174         }
9175     }
9176 }
9177
9178 static int
9179 api_dhcp_proxy_dump (vat_main_t * vam)
9180 {
9181   unformat_input_t *i = vam->input;
9182   vl_api_control_ping_t *mp_ping;
9183   vl_api_dhcp_proxy_dump_t *mp;
9184   u8 is_ipv6 = 0;
9185   int ret;
9186
9187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9188     {
9189       if (unformat (i, "ipv6"))
9190         is_ipv6 = 1;
9191       else
9192         {
9193           clib_warning ("parse error '%U'", format_unformat_error, i);
9194           return -99;
9195         }
9196     }
9197
9198   M (DHCP_PROXY_DUMP, mp);
9199
9200   mp->is_ip6 = is_ipv6;
9201   S (mp);
9202
9203   /* Use a control ping for synchronization */
9204   MPING (CONTROL_PING, mp_ping);
9205   S (mp_ping);
9206
9207   W (ret);
9208   return ret;
9209 }
9210
9211 static int
9212 api_dhcp_proxy_set_vss (vat_main_t * vam)
9213 {
9214   unformat_input_t *i = vam->input;
9215   vl_api_dhcp_proxy_set_vss_t *mp;
9216   u8 is_ipv6 = 0;
9217   u8 is_add = 1;
9218   u32 tbl_id;
9219   u8 tbl_id_set = 0;
9220   u32 oui;
9221   u8 oui_set = 0;
9222   u32 fib_id;
9223   u8 fib_id_set = 0;
9224   int ret;
9225
9226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9227     {
9228       if (unformat (i, "tbl_id %d", &tbl_id))
9229         tbl_id_set = 1;
9230       if (unformat (i, "fib_id %d", &fib_id))
9231         fib_id_set = 1;
9232       if (unformat (i, "oui %d", &oui))
9233         oui_set = 1;
9234       else if (unformat (i, "ipv6"))
9235         is_ipv6 = 1;
9236       else if (unformat (i, "del"))
9237         is_add = 0;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (tbl_id_set == 0)
9246     {
9247       errmsg ("missing tbl id");
9248       return -99;
9249     }
9250
9251   if (fib_id_set == 0)
9252     {
9253       errmsg ("missing fib id");
9254       return -99;
9255     }
9256   if (oui_set == 0)
9257     {
9258       errmsg ("missing oui");
9259       return -99;
9260     }
9261
9262   M (DHCP_PROXY_SET_VSS, mp);
9263   mp->tbl_id = ntohl (tbl_id);
9264   mp->fib_id = ntohl (fib_id);
9265   mp->oui = ntohl (oui);
9266   mp->is_ipv6 = is_ipv6;
9267   mp->is_add = is_add;
9268
9269   S (mp);
9270   W (ret);
9271   return ret;
9272 }
9273
9274 static int
9275 api_dhcp_client_config (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_dhcp_client_config_t *mp;
9279   u32 sw_if_index;
9280   u8 sw_if_index_set = 0;
9281   u8 is_add = 1;
9282   u8 *hostname = 0;
9283   u8 disable_event = 0;
9284   int ret;
9285
9286   /* Parse args required to build the message */
9287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9288     {
9289       if (unformat (i, "del"))
9290         is_add = 0;
9291       else
9292         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9293         sw_if_index_set = 1;
9294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9295         sw_if_index_set = 1;
9296       else if (unformat (i, "hostname %s", &hostname))
9297         ;
9298       else if (unformat (i, "disable_event"))
9299         disable_event = 1;
9300       else
9301         break;
9302     }
9303
9304   if (sw_if_index_set == 0)
9305     {
9306       errmsg ("missing interface name or sw_if_index");
9307       return -99;
9308     }
9309
9310   if (vec_len (hostname) > 63)
9311     {
9312       errmsg ("hostname too long");
9313     }
9314   vec_add1 (hostname, 0);
9315
9316   /* Construct the API message */
9317   M (DHCP_CLIENT_CONFIG, mp);
9318
9319   mp->sw_if_index = htonl (sw_if_index);
9320   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9321   vec_free (hostname);
9322   mp->is_add = is_add;
9323   mp->want_dhcp_event = disable_event ? 0 : 1;
9324   mp->pid = htonl (getpid ());
9325
9326   /* send it... */
9327   S (mp);
9328
9329   /* Wait for a reply, return good/bad news  */
9330   W (ret);
9331   return ret;
9332 }
9333
9334 static int
9335 api_set_ip_flow_hash (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_set_ip_flow_hash_t *mp;
9339   u32 vrf_id = 0;
9340   u8 is_ipv6 = 0;
9341   u8 vrf_id_set = 0;
9342   u8 src = 0;
9343   u8 dst = 0;
9344   u8 sport = 0;
9345   u8 dport = 0;
9346   u8 proto = 0;
9347   u8 reverse = 0;
9348   int ret;
9349
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "vrf %d", &vrf_id))
9353         vrf_id_set = 1;
9354       else if (unformat (i, "ipv6"))
9355         is_ipv6 = 1;
9356       else if (unformat (i, "src"))
9357         src = 1;
9358       else if (unformat (i, "dst"))
9359         dst = 1;
9360       else if (unformat (i, "sport"))
9361         sport = 1;
9362       else if (unformat (i, "dport"))
9363         dport = 1;
9364       else if (unformat (i, "proto"))
9365         proto = 1;
9366       else if (unformat (i, "reverse"))
9367         reverse = 1;
9368
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (vrf_id_set == 0)
9377     {
9378       errmsg ("missing vrf id");
9379       return -99;
9380     }
9381
9382   M (SET_IP_FLOW_HASH, mp);
9383   mp->src = src;
9384   mp->dst = dst;
9385   mp->sport = sport;
9386   mp->dport = dport;
9387   mp->proto = proto;
9388   mp->reverse = reverse;
9389   mp->vrf_id = ntohl (vrf_id);
9390   mp->is_ipv6 = is_ipv6;
9391
9392   S (mp);
9393   W (ret);
9394   return ret;
9395 }
9396
9397 static int
9398 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9399 {
9400   unformat_input_t *i = vam->input;
9401   vl_api_sw_interface_ip6_enable_disable_t *mp;
9402   u32 sw_if_index;
9403   u8 sw_if_index_set = 0;
9404   u8 enable = 0;
9405   int ret;
9406
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9412         sw_if_index_set = 1;
9413       else if (unformat (i, "enable"))
9414         enable = 1;
9415       else if (unformat (i, "disable"))
9416         enable = 0;
9417       else
9418         {
9419           clib_warning ("parse error '%U'", format_unformat_error, i);
9420           return -99;
9421         }
9422     }
9423
9424   if (sw_if_index_set == 0)
9425     {
9426       errmsg ("missing interface name or sw_if_index");
9427       return -99;
9428     }
9429
9430   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9431
9432   mp->sw_if_index = ntohl (sw_if_index);
9433   mp->enable = enable;
9434
9435   S (mp);
9436   W (ret);
9437   return ret;
9438 }
9439
9440 static int
9441 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9442 {
9443   unformat_input_t *i = vam->input;
9444   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9445   u32 sw_if_index;
9446   u8 sw_if_index_set = 0;
9447   u8 v6_address_set = 0;
9448   ip6_address_t v6address;
9449   int ret;
9450
9451   /* Parse args required to build the message */
9452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9453     {
9454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9455         sw_if_index_set = 1;
9456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9457         sw_if_index_set = 1;
9458       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9459         v6_address_set = 1;
9460       else
9461         break;
9462     }
9463
9464   if (sw_if_index_set == 0)
9465     {
9466       errmsg ("missing interface name or sw_if_index");
9467       return -99;
9468     }
9469   if (!v6_address_set)
9470     {
9471       errmsg ("no address set");
9472       return -99;
9473     }
9474
9475   /* Construct the API message */
9476   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9477
9478   mp->sw_if_index = ntohl (sw_if_index);
9479   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9480
9481   /* send it... */
9482   S (mp);
9483
9484   /* Wait for a reply, return good/bad news  */
9485   W (ret);
9486   return ret;
9487 }
9488
9489 static int
9490 api_ip6nd_proxy_add_del (vat_main_t * vam)
9491 {
9492   unformat_input_t *i = vam->input;
9493   vl_api_ip6nd_proxy_add_del_t *mp;
9494   u32 sw_if_index = ~0;
9495   u8 v6_address_set = 0;
9496   ip6_address_t v6address;
9497   u8 is_del = 0;
9498   int ret;
9499
9500   /* Parse args required to build the message */
9501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9502     {
9503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9504         ;
9505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9506         ;
9507       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9508         v6_address_set = 1;
9509       if (unformat (i, "del"))
9510         is_del = 1;
9511       else
9512         {
9513           clib_warning ("parse error '%U'", format_unformat_error, i);
9514           return -99;
9515         }
9516     }
9517
9518   if (sw_if_index == ~0)
9519     {
9520       errmsg ("missing interface name or sw_if_index");
9521       return -99;
9522     }
9523   if (!v6_address_set)
9524     {
9525       errmsg ("no address set");
9526       return -99;
9527     }
9528
9529   /* Construct the API message */
9530   M (IP6ND_PROXY_ADD_DEL, mp);
9531
9532   mp->is_del = is_del;
9533   mp->sw_if_index = ntohl (sw_if_index);
9534   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9535
9536   /* send it... */
9537   S (mp);
9538
9539   /* Wait for a reply, return good/bad news  */
9540   W (ret);
9541   return ret;
9542 }
9543
9544 static int
9545 api_ip6nd_proxy_dump (vat_main_t * vam)
9546 {
9547   vl_api_ip6nd_proxy_dump_t *mp;
9548   vl_api_control_ping_t *mp_ping;
9549   int ret;
9550
9551   M (IP6ND_PROXY_DUMP, mp);
9552
9553   S (mp);
9554
9555   /* Use a control ping for synchronization */
9556   MPING (CONTROL_PING, mp_ping);
9557   S (mp_ping);
9558
9559   W (ret);
9560   return ret;
9561 }
9562
9563 static void vl_api_ip6nd_proxy_details_t_handler
9564   (vl_api_ip6nd_proxy_details_t * mp)
9565 {
9566   vat_main_t *vam = &vat_main;
9567
9568   print (vam->ofp, "host %U sw_if_index %d",
9569          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9570 }
9571
9572 static void vl_api_ip6nd_proxy_details_t_handler_json
9573   (vl_api_ip6nd_proxy_details_t * mp)
9574 {
9575   vat_main_t *vam = &vat_main;
9576   struct in6_addr ip6;
9577   vat_json_node_t *node = NULL;
9578
9579   if (VAT_JSON_ARRAY != vam->json_tree.type)
9580     {
9581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9582       vat_json_init_array (&vam->json_tree);
9583     }
9584   node = vat_json_array_add (&vam->json_tree);
9585
9586   vat_json_init_object (node);
9587   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9588
9589   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9590   vat_json_object_add_ip6 (node, "host", ip6);
9591 }
9592
9593 static int
9594 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9595 {
9596   unformat_input_t *i = vam->input;
9597   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9598   u32 sw_if_index;
9599   u8 sw_if_index_set = 0;
9600   u32 address_length = 0;
9601   u8 v6_address_set = 0;
9602   ip6_address_t v6address;
9603   u8 use_default = 0;
9604   u8 no_advertise = 0;
9605   u8 off_link = 0;
9606   u8 no_autoconfig = 0;
9607   u8 no_onlink = 0;
9608   u8 is_no = 0;
9609   u32 val_lifetime = 0;
9610   u32 pref_lifetime = 0;
9611   int ret;
9612
9613   /* Parse args required to build the message */
9614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9615     {
9616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9617         sw_if_index_set = 1;
9618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9619         sw_if_index_set = 1;
9620       else if (unformat (i, "%U/%d",
9621                          unformat_ip6_address, &v6address, &address_length))
9622         v6_address_set = 1;
9623       else if (unformat (i, "val_life %d", &val_lifetime))
9624         ;
9625       else if (unformat (i, "pref_life %d", &pref_lifetime))
9626         ;
9627       else if (unformat (i, "def"))
9628         use_default = 1;
9629       else if (unformat (i, "noadv"))
9630         no_advertise = 1;
9631       else if (unformat (i, "offl"))
9632         off_link = 1;
9633       else if (unformat (i, "noauto"))
9634         no_autoconfig = 1;
9635       else if (unformat (i, "nolink"))
9636         no_onlink = 1;
9637       else if (unformat (i, "isno"))
9638         is_no = 1;
9639       else
9640         {
9641           clib_warning ("parse error '%U'", format_unformat_error, i);
9642           return -99;
9643         }
9644     }
9645
9646   if (sw_if_index_set == 0)
9647     {
9648       errmsg ("missing interface name or sw_if_index");
9649       return -99;
9650     }
9651   if (!v6_address_set)
9652     {
9653       errmsg ("no address set");
9654       return -99;
9655     }
9656
9657   /* Construct the API message */
9658   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9659
9660   mp->sw_if_index = ntohl (sw_if_index);
9661   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9662   mp->address_length = address_length;
9663   mp->use_default = use_default;
9664   mp->no_advertise = no_advertise;
9665   mp->off_link = off_link;
9666   mp->no_autoconfig = no_autoconfig;
9667   mp->no_onlink = no_onlink;
9668   mp->is_no = is_no;
9669   mp->val_lifetime = ntohl (val_lifetime);
9670   mp->pref_lifetime = ntohl (pref_lifetime);
9671
9672   /* send it... */
9673   S (mp);
9674
9675   /* Wait for a reply, return good/bad news  */
9676   W (ret);
9677   return ret;
9678 }
9679
9680 static int
9681 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9685   u32 sw_if_index;
9686   u8 sw_if_index_set = 0;
9687   u8 suppress = 0;
9688   u8 managed = 0;
9689   u8 other = 0;
9690   u8 ll_option = 0;
9691   u8 send_unicast = 0;
9692   u8 cease = 0;
9693   u8 is_no = 0;
9694   u8 default_router = 0;
9695   u32 max_interval = 0;
9696   u32 min_interval = 0;
9697   u32 lifetime = 0;
9698   u32 initial_count = 0;
9699   u32 initial_interval = 0;
9700   int ret;
9701
9702
9703   /* Parse args required to build the message */
9704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9707         sw_if_index_set = 1;
9708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9709         sw_if_index_set = 1;
9710       else if (unformat (i, "maxint %d", &max_interval))
9711         ;
9712       else if (unformat (i, "minint %d", &min_interval))
9713         ;
9714       else if (unformat (i, "life %d", &lifetime))
9715         ;
9716       else if (unformat (i, "count %d", &initial_count))
9717         ;
9718       else if (unformat (i, "interval %d", &initial_interval))
9719         ;
9720       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9721         suppress = 1;
9722       else if (unformat (i, "managed"))
9723         managed = 1;
9724       else if (unformat (i, "other"))
9725         other = 1;
9726       else if (unformat (i, "ll"))
9727         ll_option = 1;
9728       else if (unformat (i, "send"))
9729         send_unicast = 1;
9730       else if (unformat (i, "cease"))
9731         cease = 1;
9732       else if (unformat (i, "isno"))
9733         is_no = 1;
9734       else if (unformat (i, "def"))
9735         default_router = 1;
9736       else
9737         {
9738           clib_warning ("parse error '%U'", format_unformat_error, i);
9739           return -99;
9740         }
9741     }
9742
9743   if (sw_if_index_set == 0)
9744     {
9745       errmsg ("missing interface name or sw_if_index");
9746       return -99;
9747     }
9748
9749   /* Construct the API message */
9750   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9751
9752   mp->sw_if_index = ntohl (sw_if_index);
9753   mp->max_interval = ntohl (max_interval);
9754   mp->min_interval = ntohl (min_interval);
9755   mp->lifetime = ntohl (lifetime);
9756   mp->initial_count = ntohl (initial_count);
9757   mp->initial_interval = ntohl (initial_interval);
9758   mp->suppress = suppress;
9759   mp->managed = managed;
9760   mp->other = other;
9761   mp->ll_option = ll_option;
9762   mp->send_unicast = send_unicast;
9763   mp->cease = cease;
9764   mp->is_no = is_no;
9765   mp->default_router = default_router;
9766
9767   /* send it... */
9768   S (mp);
9769
9770   /* Wait for a reply, return good/bad news  */
9771   W (ret);
9772   return ret;
9773 }
9774
9775 static int
9776 api_set_arp_neighbor_limit (vat_main_t * vam)
9777 {
9778   unformat_input_t *i = vam->input;
9779   vl_api_set_arp_neighbor_limit_t *mp;
9780   u32 arp_nbr_limit;
9781   u8 limit_set = 0;
9782   u8 is_ipv6 = 0;
9783   int ret;
9784
9785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9786     {
9787       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9788         limit_set = 1;
9789       else if (unformat (i, "ipv6"))
9790         is_ipv6 = 1;
9791       else
9792         {
9793           clib_warning ("parse error '%U'", format_unformat_error, i);
9794           return -99;
9795         }
9796     }
9797
9798   if (limit_set == 0)
9799     {
9800       errmsg ("missing limit value");
9801       return -99;
9802     }
9803
9804   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9805
9806   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9807   mp->is_ipv6 = is_ipv6;
9808
9809   S (mp);
9810   W (ret);
9811   return ret;
9812 }
9813
9814 static int
9815 api_l2_patch_add_del (vat_main_t * vam)
9816 {
9817   unformat_input_t *i = vam->input;
9818   vl_api_l2_patch_add_del_t *mp;
9819   u32 rx_sw_if_index;
9820   u8 rx_sw_if_index_set = 0;
9821   u32 tx_sw_if_index;
9822   u8 tx_sw_if_index_set = 0;
9823   u8 is_add = 1;
9824   int ret;
9825
9826   /* Parse args required to build the message */
9827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9830         rx_sw_if_index_set = 1;
9831       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9832         tx_sw_if_index_set = 1;
9833       else if (unformat (i, "rx"))
9834         {
9835           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836             {
9837               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9838                             &rx_sw_if_index))
9839                 rx_sw_if_index_set = 1;
9840             }
9841           else
9842             break;
9843         }
9844       else if (unformat (i, "tx"))
9845         {
9846           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9847             {
9848               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9849                             &tx_sw_if_index))
9850                 tx_sw_if_index_set = 1;
9851             }
9852           else
9853             break;
9854         }
9855       else if (unformat (i, "del"))
9856         is_add = 0;
9857       else
9858         break;
9859     }
9860
9861   if (rx_sw_if_index_set == 0)
9862     {
9863       errmsg ("missing rx interface name or rx_sw_if_index");
9864       return -99;
9865     }
9866
9867   if (tx_sw_if_index_set == 0)
9868     {
9869       errmsg ("missing tx interface name or tx_sw_if_index");
9870       return -99;
9871     }
9872
9873   M (L2_PATCH_ADD_DEL, mp);
9874
9875   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9876   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9877   mp->is_add = is_add;
9878
9879   S (mp);
9880   W (ret);
9881   return ret;
9882 }
9883
9884 u8 is_del;
9885 u8 localsid_addr[16];
9886 u8 end_psp;
9887 u8 behavior;
9888 u32 sw_if_index;
9889 u32 vlan_index;
9890 u32 fib_table;
9891 u8 nh_addr[16];
9892
9893 static int
9894 api_sr_localsid_add_del (vat_main_t * vam)
9895 {
9896   unformat_input_t *i = vam->input;
9897   vl_api_sr_localsid_add_del_t *mp;
9898
9899   u8 is_del;
9900   ip6_address_t localsid;
9901   u8 end_psp = 0;
9902   u8 behavior = ~0;
9903   u32 sw_if_index;
9904   u32 fib_table = ~(u32) 0;
9905   ip6_address_t next_hop;
9906
9907   bool nexthop_set = 0;
9908
9909   int ret;
9910
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "del"))
9914         is_del = 1;
9915       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9916       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9917         nexthop_set = 1;
9918       else if (unformat (i, "behavior %u", &behavior));
9919       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9920       else if (unformat (i, "fib-table %u", &fib_table));
9921       else if (unformat (i, "end.psp %u", &behavior));
9922       else
9923         break;
9924     }
9925
9926   M (SR_LOCALSID_ADD_DEL, mp);
9927
9928   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9929   if (nexthop_set)
9930     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9931   mp->behavior = behavior;
9932   mp->sw_if_index = ntohl (sw_if_index);
9933   mp->fib_table = ntohl (fib_table);
9934   mp->end_psp = end_psp;
9935   mp->is_del = is_del;
9936
9937   S (mp);
9938   W (ret);
9939   return ret;
9940 }
9941
9942 static int
9943 api_ioam_enable (vat_main_t * vam)
9944 {
9945   unformat_input_t *input = vam->input;
9946   vl_api_ioam_enable_t *mp;
9947   u32 id = 0;
9948   int has_trace_option = 0;
9949   int has_pot_option = 0;
9950   int has_seqno_option = 0;
9951   int has_analyse_option = 0;
9952   int ret;
9953
9954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (unformat (input, "trace"))
9957         has_trace_option = 1;
9958       else if (unformat (input, "pot"))
9959         has_pot_option = 1;
9960       else if (unformat (input, "seqno"))
9961         has_seqno_option = 1;
9962       else if (unformat (input, "analyse"))
9963         has_analyse_option = 1;
9964       else
9965         break;
9966     }
9967   M (IOAM_ENABLE, mp);
9968   mp->id = htons (id);
9969   mp->seqno = has_seqno_option;
9970   mp->analyse = has_analyse_option;
9971   mp->pot_enable = has_pot_option;
9972   mp->trace_enable = has_trace_option;
9973
9974   S (mp);
9975   W (ret);
9976   return ret;
9977 }
9978
9979
9980 static int
9981 api_ioam_disable (vat_main_t * vam)
9982 {
9983   vl_api_ioam_disable_t *mp;
9984   int ret;
9985
9986   M (IOAM_DISABLE, mp);
9987   S (mp);
9988   W (ret);
9989   return ret;
9990 }
9991
9992 #define foreach_tcp_proto_field                 \
9993 _(src_port)                                     \
9994 _(dst_port)
9995
9996 #define foreach_udp_proto_field                 \
9997 _(src_port)                                     \
9998 _(dst_port)
9999
10000 #define foreach_ip4_proto_field                 \
10001 _(src_address)                                  \
10002 _(dst_address)                                  \
10003 _(tos)                                          \
10004 _(length)                                       \
10005 _(fragment_id)                                  \
10006 _(ttl)                                          \
10007 _(protocol)                                     \
10008 _(checksum)
10009
10010 typedef struct
10011 {
10012   u16 src_port, dst_port;
10013 } tcpudp_header_t;
10014
10015 #if VPP_API_TEST_BUILTIN == 0
10016 uword
10017 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10018 {
10019   u8 **maskp = va_arg (*args, u8 **);
10020   u8 *mask = 0;
10021   u8 found_something = 0;
10022   tcp_header_t *tcp;
10023
10024 #define _(a) u8 a=0;
10025   foreach_tcp_proto_field;
10026 #undef _
10027
10028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10029     {
10030       if (0);
10031 #define _(a) else if (unformat (input, #a)) a=1;
10032       foreach_tcp_proto_field
10033 #undef _
10034         else
10035         break;
10036     }
10037
10038 #define _(a) found_something += a;
10039   foreach_tcp_proto_field;
10040 #undef _
10041
10042   if (found_something == 0)
10043     return 0;
10044
10045   vec_validate (mask, sizeof (*tcp) - 1);
10046
10047   tcp = (tcp_header_t *) mask;
10048
10049 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10050   foreach_tcp_proto_field;
10051 #undef _
10052
10053   *maskp = mask;
10054   return 1;
10055 }
10056
10057 uword
10058 unformat_udp_mask (unformat_input_t * input, va_list * args)
10059 {
10060   u8 **maskp = va_arg (*args, u8 **);
10061   u8 *mask = 0;
10062   u8 found_something = 0;
10063   udp_header_t *udp;
10064
10065 #define _(a) u8 a=0;
10066   foreach_udp_proto_field;
10067 #undef _
10068
10069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10070     {
10071       if (0);
10072 #define _(a) else if (unformat (input, #a)) a=1;
10073       foreach_udp_proto_field
10074 #undef _
10075         else
10076         break;
10077     }
10078
10079 #define _(a) found_something += a;
10080   foreach_udp_proto_field;
10081 #undef _
10082
10083   if (found_something == 0)
10084     return 0;
10085
10086   vec_validate (mask, sizeof (*udp) - 1);
10087
10088   udp = (udp_header_t *) mask;
10089
10090 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10091   foreach_udp_proto_field;
10092 #undef _
10093
10094   *maskp = mask;
10095   return 1;
10096 }
10097
10098 uword
10099 unformat_l4_mask (unformat_input_t * input, va_list * args)
10100 {
10101   u8 **maskp = va_arg (*args, u8 **);
10102   u16 src_port = 0, dst_port = 0;
10103   tcpudp_header_t *tcpudp;
10104
10105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10108         return 1;
10109       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10110         return 1;
10111       else if (unformat (input, "src_port"))
10112         src_port = 0xFFFF;
10113       else if (unformat (input, "dst_port"))
10114         dst_port = 0xFFFF;
10115       else
10116         return 0;
10117     }
10118
10119   if (!src_port && !dst_port)
10120     return 0;
10121
10122   u8 *mask = 0;
10123   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10124
10125   tcpudp = (tcpudp_header_t *) mask;
10126   tcpudp->src_port = src_port;
10127   tcpudp->dst_port = dst_port;
10128
10129   *maskp = mask;
10130
10131   return 1;
10132 }
10133
10134 uword
10135 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10136 {
10137   u8 **maskp = va_arg (*args, u8 **);
10138   u8 *mask = 0;
10139   u8 found_something = 0;
10140   ip4_header_t *ip;
10141
10142 #define _(a) u8 a=0;
10143   foreach_ip4_proto_field;
10144 #undef _
10145   u8 version = 0;
10146   u8 hdr_length = 0;
10147
10148
10149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (input, "version"))
10152         version = 1;
10153       else if (unformat (input, "hdr_length"))
10154         hdr_length = 1;
10155       else if (unformat (input, "src"))
10156         src_address = 1;
10157       else if (unformat (input, "dst"))
10158         dst_address = 1;
10159       else if (unformat (input, "proto"))
10160         protocol = 1;
10161
10162 #define _(a) else if (unformat (input, #a)) a=1;
10163       foreach_ip4_proto_field
10164 #undef _
10165         else
10166         break;
10167     }
10168
10169 #define _(a) found_something += a;
10170   foreach_ip4_proto_field;
10171 #undef _
10172
10173   if (found_something == 0)
10174     return 0;
10175
10176   vec_validate (mask, sizeof (*ip) - 1);
10177
10178   ip = (ip4_header_t *) mask;
10179
10180 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10181   foreach_ip4_proto_field;
10182 #undef _
10183
10184   ip->ip_version_and_header_length = 0;
10185
10186   if (version)
10187     ip->ip_version_and_header_length |= 0xF0;
10188
10189   if (hdr_length)
10190     ip->ip_version_and_header_length |= 0x0F;
10191
10192   *maskp = mask;
10193   return 1;
10194 }
10195
10196 #define foreach_ip6_proto_field                 \
10197 _(src_address)                                  \
10198 _(dst_address)                                  \
10199 _(payload_length)                               \
10200 _(hop_limit)                                    \
10201 _(protocol)
10202
10203 uword
10204 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10205 {
10206   u8 **maskp = va_arg (*args, u8 **);
10207   u8 *mask = 0;
10208   u8 found_something = 0;
10209   ip6_header_t *ip;
10210   u32 ip_version_traffic_class_and_flow_label;
10211
10212 #define _(a) u8 a=0;
10213   foreach_ip6_proto_field;
10214 #undef _
10215   u8 version = 0;
10216   u8 traffic_class = 0;
10217   u8 flow_label = 0;
10218
10219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (input, "version"))
10222         version = 1;
10223       else if (unformat (input, "traffic-class"))
10224         traffic_class = 1;
10225       else if (unformat (input, "flow-label"))
10226         flow_label = 1;
10227       else if (unformat (input, "src"))
10228         src_address = 1;
10229       else if (unformat (input, "dst"))
10230         dst_address = 1;
10231       else if (unformat (input, "proto"))
10232         protocol = 1;
10233
10234 #define _(a) else if (unformat (input, #a)) a=1;
10235       foreach_ip6_proto_field
10236 #undef _
10237         else
10238         break;
10239     }
10240
10241 #define _(a) found_something += a;
10242   foreach_ip6_proto_field;
10243 #undef _
10244
10245   if (found_something == 0)
10246     return 0;
10247
10248   vec_validate (mask, sizeof (*ip) - 1);
10249
10250   ip = (ip6_header_t *) mask;
10251
10252 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10253   foreach_ip6_proto_field;
10254 #undef _
10255
10256   ip_version_traffic_class_and_flow_label = 0;
10257
10258   if (version)
10259     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10260
10261   if (traffic_class)
10262     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10263
10264   if (flow_label)
10265     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10266
10267   ip->ip_version_traffic_class_and_flow_label =
10268     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10269
10270   *maskp = mask;
10271   return 1;
10272 }
10273
10274 uword
10275 unformat_l3_mask (unformat_input_t * input, va_list * args)
10276 {
10277   u8 **maskp = va_arg (*args, u8 **);
10278
10279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10280     {
10281       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10282         return 1;
10283       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10284         return 1;
10285       else
10286         break;
10287     }
10288   return 0;
10289 }
10290
10291 uword
10292 unformat_l2_mask (unformat_input_t * input, va_list * args)
10293 {
10294   u8 **maskp = va_arg (*args, u8 **);
10295   u8 *mask = 0;
10296   u8 src = 0;
10297   u8 dst = 0;
10298   u8 proto = 0;
10299   u8 tag1 = 0;
10300   u8 tag2 = 0;
10301   u8 ignore_tag1 = 0;
10302   u8 ignore_tag2 = 0;
10303   u8 cos1 = 0;
10304   u8 cos2 = 0;
10305   u8 dot1q = 0;
10306   u8 dot1ad = 0;
10307   int len = 14;
10308
10309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (input, "src"))
10312         src = 1;
10313       else if (unformat (input, "dst"))
10314         dst = 1;
10315       else if (unformat (input, "proto"))
10316         proto = 1;
10317       else if (unformat (input, "tag1"))
10318         tag1 = 1;
10319       else if (unformat (input, "tag2"))
10320         tag2 = 1;
10321       else if (unformat (input, "ignore-tag1"))
10322         ignore_tag1 = 1;
10323       else if (unformat (input, "ignore-tag2"))
10324         ignore_tag2 = 1;
10325       else if (unformat (input, "cos1"))
10326         cos1 = 1;
10327       else if (unformat (input, "cos2"))
10328         cos2 = 1;
10329       else if (unformat (input, "dot1q"))
10330         dot1q = 1;
10331       else if (unformat (input, "dot1ad"))
10332         dot1ad = 1;
10333       else
10334         break;
10335     }
10336   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10337        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10338     return 0;
10339
10340   if (tag1 || ignore_tag1 || cos1 || dot1q)
10341     len = 18;
10342   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10343     len = 22;
10344
10345   vec_validate (mask, len - 1);
10346
10347   if (dst)
10348     memset (mask, 0xff, 6);
10349
10350   if (src)
10351     memset (mask + 6, 0xff, 6);
10352
10353   if (tag2 || dot1ad)
10354     {
10355       /* inner vlan tag */
10356       if (tag2)
10357         {
10358           mask[19] = 0xff;
10359           mask[18] = 0x0f;
10360         }
10361       if (cos2)
10362         mask[18] |= 0xe0;
10363       if (proto)
10364         mask[21] = mask[20] = 0xff;
10365       if (tag1)
10366         {
10367           mask[15] = 0xff;
10368           mask[14] = 0x0f;
10369         }
10370       if (cos1)
10371         mask[14] |= 0xe0;
10372       *maskp = mask;
10373       return 1;
10374     }
10375   if (tag1 | dot1q)
10376     {
10377       if (tag1)
10378         {
10379           mask[15] = 0xff;
10380           mask[14] = 0x0f;
10381         }
10382       if (cos1)
10383         mask[14] |= 0xe0;
10384       if (proto)
10385         mask[16] = mask[17] = 0xff;
10386
10387       *maskp = mask;
10388       return 1;
10389     }
10390   if (cos2)
10391     mask[18] |= 0xe0;
10392   if (cos1)
10393     mask[14] |= 0xe0;
10394   if (proto)
10395     mask[12] = mask[13] = 0xff;
10396
10397   *maskp = mask;
10398   return 1;
10399 }
10400
10401 uword
10402 unformat_classify_mask (unformat_input_t * input, va_list * args)
10403 {
10404   u8 **maskp = va_arg (*args, u8 **);
10405   u32 *skipp = va_arg (*args, u32 *);
10406   u32 *matchp = va_arg (*args, u32 *);
10407   u32 match;
10408   u8 *mask = 0;
10409   u8 *l2 = 0;
10410   u8 *l3 = 0;
10411   u8 *l4 = 0;
10412   int i;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10417         ;
10418       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10419         ;
10420       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10421         ;
10422       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10423         ;
10424       else
10425         break;
10426     }
10427
10428   if (l4 && !l3)
10429     {
10430       vec_free (mask);
10431       vec_free (l2);
10432       vec_free (l4);
10433       return 0;
10434     }
10435
10436   if (mask || l2 || l3 || l4)
10437     {
10438       if (l2 || l3 || l4)
10439         {
10440           /* "With a free Ethernet header in every package" */
10441           if (l2 == 0)
10442             vec_validate (l2, 13);
10443           mask = l2;
10444           if (vec_len (l3))
10445             {
10446               vec_append (mask, l3);
10447               vec_free (l3);
10448             }
10449           if (vec_len (l4))
10450             {
10451               vec_append (mask, l4);
10452               vec_free (l4);
10453             }
10454         }
10455
10456       /* Scan forward looking for the first significant mask octet */
10457       for (i = 0; i < vec_len (mask); i++)
10458         if (mask[i])
10459           break;
10460
10461       /* compute (skip, match) params */
10462       *skipp = i / sizeof (u32x4);
10463       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10464
10465       /* Pad mask to an even multiple of the vector size */
10466       while (vec_len (mask) % sizeof (u32x4))
10467         vec_add1 (mask, 0);
10468
10469       match = vec_len (mask) / sizeof (u32x4);
10470
10471       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10472         {
10473           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10474           if (*tmp || *(tmp + 1))
10475             break;
10476           match--;
10477         }
10478       if (match == 0)
10479         clib_warning ("BUG: match 0");
10480
10481       _vec_len (mask) = match * sizeof (u32x4);
10482
10483       *matchp = match;
10484       *maskp = mask;
10485
10486       return 1;
10487     }
10488
10489   return 0;
10490 }
10491 #endif /* VPP_API_TEST_BUILTIN */
10492
10493 #define foreach_l2_next                         \
10494 _(drop, DROP)                                   \
10495 _(ethernet, ETHERNET_INPUT)                     \
10496 _(ip4, IP4_INPUT)                               \
10497 _(ip6, IP6_INPUT)
10498
10499 uword
10500 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10501 {
10502   u32 *miss_next_indexp = va_arg (*args, u32 *);
10503   u32 next_index = 0;
10504   u32 tmp;
10505
10506 #define _(n,N) \
10507   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10508   foreach_l2_next;
10509 #undef _
10510
10511   if (unformat (input, "%d", &tmp))
10512     {
10513       next_index = tmp;
10514       goto out;
10515     }
10516
10517   return 0;
10518
10519 out:
10520   *miss_next_indexp = next_index;
10521   return 1;
10522 }
10523
10524 #define foreach_ip_next                         \
10525 _(drop, DROP)                                   \
10526 _(local, LOCAL)                                 \
10527 _(rewrite, REWRITE)
10528
10529 uword
10530 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10531 {
10532   u32 *miss_next_indexp = va_arg (*args, u32 *);
10533   u32 next_index = 0;
10534   u32 tmp;
10535
10536 #define _(n,N) \
10537   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10538   foreach_ip_next;
10539 #undef _
10540
10541   if (unformat (input, "%d", &tmp))
10542     {
10543       next_index = tmp;
10544       goto out;
10545     }
10546
10547   return 0;
10548
10549 out:
10550   *miss_next_indexp = next_index;
10551   return 1;
10552 }
10553
10554 #define foreach_acl_next                        \
10555 _(deny, DENY)
10556
10557 uword
10558 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10559 {
10560   u32 *miss_next_indexp = va_arg (*args, u32 *);
10561   u32 next_index = 0;
10562   u32 tmp;
10563
10564 #define _(n,N) \
10565   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10566   foreach_acl_next;
10567 #undef _
10568
10569   if (unformat (input, "permit"))
10570     {
10571       next_index = ~0;
10572       goto out;
10573     }
10574   else if (unformat (input, "%d", &tmp))
10575     {
10576       next_index = tmp;
10577       goto out;
10578     }
10579
10580   return 0;
10581
10582 out:
10583   *miss_next_indexp = next_index;
10584   return 1;
10585 }
10586
10587 uword
10588 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10589 {
10590   u32 *r = va_arg (*args, u32 *);
10591
10592   if (unformat (input, "conform-color"))
10593     *r = POLICE_CONFORM;
10594   else if (unformat (input, "exceed-color"))
10595     *r = POLICE_EXCEED;
10596   else
10597     return 0;
10598
10599   return 1;
10600 }
10601
10602 static int
10603 api_classify_add_del_table (vat_main_t * vam)
10604 {
10605   unformat_input_t *i = vam->input;
10606   vl_api_classify_add_del_table_t *mp;
10607
10608   u32 nbuckets = 2;
10609   u32 skip = ~0;
10610   u32 match = ~0;
10611   int is_add = 1;
10612   int del_chain = 0;
10613   u32 table_index = ~0;
10614   u32 next_table_index = ~0;
10615   u32 miss_next_index = ~0;
10616   u32 memory_size = 32 << 20;
10617   u8 *mask = 0;
10618   u32 current_data_flag = 0;
10619   int current_data_offset = 0;
10620   int ret;
10621
10622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10623     {
10624       if (unformat (i, "del"))
10625         is_add = 0;
10626       else if (unformat (i, "del-chain"))
10627         {
10628           is_add = 0;
10629           del_chain = 1;
10630         }
10631       else if (unformat (i, "buckets %d", &nbuckets))
10632         ;
10633       else if (unformat (i, "memory_size %d", &memory_size))
10634         ;
10635       else if (unformat (i, "skip %d", &skip))
10636         ;
10637       else if (unformat (i, "match %d", &match))
10638         ;
10639       else if (unformat (i, "table %d", &table_index))
10640         ;
10641       else if (unformat (i, "mask %U", unformat_classify_mask,
10642                          &mask, &skip, &match))
10643         ;
10644       else if (unformat (i, "next-table %d", &next_table_index))
10645         ;
10646       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10647                          &miss_next_index))
10648         ;
10649       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10650                          &miss_next_index))
10651         ;
10652       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10653                          &miss_next_index))
10654         ;
10655       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10656         ;
10657       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10658         ;
10659       else
10660         break;
10661     }
10662
10663   if (is_add && mask == 0)
10664     {
10665       errmsg ("Mask required");
10666       return -99;
10667     }
10668
10669   if (is_add && skip == ~0)
10670     {
10671       errmsg ("skip count required");
10672       return -99;
10673     }
10674
10675   if (is_add && match == ~0)
10676     {
10677       errmsg ("match count required");
10678       return -99;
10679     }
10680
10681   if (!is_add && table_index == ~0)
10682     {
10683       errmsg ("table index required for delete");
10684       return -99;
10685     }
10686
10687   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10688
10689   mp->is_add = is_add;
10690   mp->del_chain = del_chain;
10691   mp->table_index = ntohl (table_index);
10692   mp->nbuckets = ntohl (nbuckets);
10693   mp->memory_size = ntohl (memory_size);
10694   mp->skip_n_vectors = ntohl (skip);
10695   mp->match_n_vectors = ntohl (match);
10696   mp->next_table_index = ntohl (next_table_index);
10697   mp->miss_next_index = ntohl (miss_next_index);
10698   mp->current_data_flag = ntohl (current_data_flag);
10699   mp->current_data_offset = ntohl (current_data_offset);
10700   clib_memcpy (mp->mask, mask, vec_len (mask));
10701
10702   vec_free (mask);
10703
10704   S (mp);
10705   W (ret);
10706   return ret;
10707 }
10708
10709 #if VPP_API_TEST_BUILTIN == 0
10710 uword
10711 unformat_l4_match (unformat_input_t * input, va_list * args)
10712 {
10713   u8 **matchp = va_arg (*args, u8 **);
10714
10715   u8 *proto_header = 0;
10716   int src_port = 0;
10717   int dst_port = 0;
10718
10719   tcpudp_header_t h;
10720
10721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (input, "src_port %d", &src_port))
10724         ;
10725       else if (unformat (input, "dst_port %d", &dst_port))
10726         ;
10727       else
10728         return 0;
10729     }
10730
10731   h.src_port = clib_host_to_net_u16 (src_port);
10732   h.dst_port = clib_host_to_net_u16 (dst_port);
10733   vec_validate (proto_header, sizeof (h) - 1);
10734   memcpy (proto_header, &h, sizeof (h));
10735
10736   *matchp = proto_header;
10737
10738   return 1;
10739 }
10740
10741 uword
10742 unformat_ip4_match (unformat_input_t * input, va_list * args)
10743 {
10744   u8 **matchp = va_arg (*args, u8 **);
10745   u8 *match = 0;
10746   ip4_header_t *ip;
10747   int version = 0;
10748   u32 version_val;
10749   int hdr_length = 0;
10750   u32 hdr_length_val;
10751   int src = 0, dst = 0;
10752   ip4_address_t src_val, dst_val;
10753   int proto = 0;
10754   u32 proto_val;
10755   int tos = 0;
10756   u32 tos_val;
10757   int length = 0;
10758   u32 length_val;
10759   int fragment_id = 0;
10760   u32 fragment_id_val;
10761   int ttl = 0;
10762   int ttl_val;
10763   int checksum = 0;
10764   u32 checksum_val;
10765
10766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10767     {
10768       if (unformat (input, "version %d", &version_val))
10769         version = 1;
10770       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10771         hdr_length = 1;
10772       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10773         src = 1;
10774       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10775         dst = 1;
10776       else if (unformat (input, "proto %d", &proto_val))
10777         proto = 1;
10778       else if (unformat (input, "tos %d", &tos_val))
10779         tos = 1;
10780       else if (unformat (input, "length %d", &length_val))
10781         length = 1;
10782       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10783         fragment_id = 1;
10784       else if (unformat (input, "ttl %d", &ttl_val))
10785         ttl = 1;
10786       else if (unformat (input, "checksum %d", &checksum_val))
10787         checksum = 1;
10788       else
10789         break;
10790     }
10791
10792   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10793       + ttl + checksum == 0)
10794     return 0;
10795
10796   /*
10797    * Aligned because we use the real comparison functions
10798    */
10799   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10800
10801   ip = (ip4_header_t *) match;
10802
10803   /* These are realistically matched in practice */
10804   if (src)
10805     ip->src_address.as_u32 = src_val.as_u32;
10806
10807   if (dst)
10808     ip->dst_address.as_u32 = dst_val.as_u32;
10809
10810   if (proto)
10811     ip->protocol = proto_val;
10812
10813
10814   /* These are not, but they're included for completeness */
10815   if (version)
10816     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10817
10818   if (hdr_length)
10819     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10820
10821   if (tos)
10822     ip->tos = tos_val;
10823
10824   if (length)
10825     ip->length = clib_host_to_net_u16 (length_val);
10826
10827   if (ttl)
10828     ip->ttl = ttl_val;
10829
10830   if (checksum)
10831     ip->checksum = clib_host_to_net_u16 (checksum_val);
10832
10833   *matchp = match;
10834   return 1;
10835 }
10836
10837 uword
10838 unformat_ip6_match (unformat_input_t * input, va_list * args)
10839 {
10840   u8 **matchp = va_arg (*args, u8 **);
10841   u8 *match = 0;
10842   ip6_header_t *ip;
10843   int version = 0;
10844   u32 version_val;
10845   u8 traffic_class = 0;
10846   u32 traffic_class_val = 0;
10847   u8 flow_label = 0;
10848   u8 flow_label_val;
10849   int src = 0, dst = 0;
10850   ip6_address_t src_val, dst_val;
10851   int proto = 0;
10852   u32 proto_val;
10853   int payload_length = 0;
10854   u32 payload_length_val;
10855   int hop_limit = 0;
10856   int hop_limit_val;
10857   u32 ip_version_traffic_class_and_flow_label;
10858
10859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (input, "version %d", &version_val))
10862         version = 1;
10863       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10864         traffic_class = 1;
10865       else if (unformat (input, "flow_label %d", &flow_label_val))
10866         flow_label = 1;
10867       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10868         src = 1;
10869       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10870         dst = 1;
10871       else if (unformat (input, "proto %d", &proto_val))
10872         proto = 1;
10873       else if (unformat (input, "payload_length %d", &payload_length_val))
10874         payload_length = 1;
10875       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10876         hop_limit = 1;
10877       else
10878         break;
10879     }
10880
10881   if (version + traffic_class + flow_label + src + dst + proto +
10882       payload_length + hop_limit == 0)
10883     return 0;
10884
10885   /*
10886    * Aligned because we use the real comparison functions
10887    */
10888   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10889
10890   ip = (ip6_header_t *) match;
10891
10892   if (src)
10893     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10894
10895   if (dst)
10896     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10897
10898   if (proto)
10899     ip->protocol = proto_val;
10900
10901   ip_version_traffic_class_and_flow_label = 0;
10902
10903   if (version)
10904     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10905
10906   if (traffic_class)
10907     ip_version_traffic_class_and_flow_label |=
10908       (traffic_class_val & 0xFF) << 20;
10909
10910   if (flow_label)
10911     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10912
10913   ip->ip_version_traffic_class_and_flow_label =
10914     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10915
10916   if (payload_length)
10917     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10918
10919   if (hop_limit)
10920     ip->hop_limit = hop_limit_val;
10921
10922   *matchp = match;
10923   return 1;
10924 }
10925
10926 uword
10927 unformat_l3_match (unformat_input_t * input, va_list * args)
10928 {
10929   u8 **matchp = va_arg (*args, u8 **);
10930
10931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10932     {
10933       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10934         return 1;
10935       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10936         return 1;
10937       else
10938         break;
10939     }
10940   return 0;
10941 }
10942
10943 uword
10944 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10945 {
10946   u8 *tagp = va_arg (*args, u8 *);
10947   u32 tag;
10948
10949   if (unformat (input, "%d", &tag))
10950     {
10951       tagp[0] = (tag >> 8) & 0x0F;
10952       tagp[1] = tag & 0xFF;
10953       return 1;
10954     }
10955
10956   return 0;
10957 }
10958
10959 uword
10960 unformat_l2_match (unformat_input_t * input, va_list * args)
10961 {
10962   u8 **matchp = va_arg (*args, u8 **);
10963   u8 *match = 0;
10964   u8 src = 0;
10965   u8 src_val[6];
10966   u8 dst = 0;
10967   u8 dst_val[6];
10968   u8 proto = 0;
10969   u16 proto_val;
10970   u8 tag1 = 0;
10971   u8 tag1_val[2];
10972   u8 tag2 = 0;
10973   u8 tag2_val[2];
10974   int len = 14;
10975   u8 ignore_tag1 = 0;
10976   u8 ignore_tag2 = 0;
10977   u8 cos1 = 0;
10978   u8 cos2 = 0;
10979   u32 cos1_val = 0;
10980   u32 cos2_val = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10985         src = 1;
10986       else
10987         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10988         dst = 1;
10989       else if (unformat (input, "proto %U",
10990                          unformat_ethernet_type_host_byte_order, &proto_val))
10991         proto = 1;
10992       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10993         tag1 = 1;
10994       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10995         tag2 = 1;
10996       else if (unformat (input, "ignore-tag1"))
10997         ignore_tag1 = 1;
10998       else if (unformat (input, "ignore-tag2"))
10999         ignore_tag2 = 1;
11000       else if (unformat (input, "cos1 %d", &cos1_val))
11001         cos1 = 1;
11002       else if (unformat (input, "cos2 %d", &cos2_val))
11003         cos2 = 1;
11004       else
11005         break;
11006     }
11007   if ((src + dst + proto + tag1 + tag2 +
11008        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11009     return 0;
11010
11011   if (tag1 || ignore_tag1 || cos1)
11012     len = 18;
11013   if (tag2 || ignore_tag2 || cos2)
11014     len = 22;
11015
11016   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11017
11018   if (dst)
11019     clib_memcpy (match, dst_val, 6);
11020
11021   if (src)
11022     clib_memcpy (match + 6, src_val, 6);
11023
11024   if (tag2)
11025     {
11026       /* inner vlan tag */
11027       match[19] = tag2_val[1];
11028       match[18] = tag2_val[0];
11029       if (cos2)
11030         match[18] |= (cos2_val & 0x7) << 5;
11031       if (proto)
11032         {
11033           match[21] = proto_val & 0xff;
11034           match[20] = proto_val >> 8;
11035         }
11036       if (tag1)
11037         {
11038           match[15] = tag1_val[1];
11039           match[14] = tag1_val[0];
11040         }
11041       if (cos1)
11042         match[14] |= (cos1_val & 0x7) << 5;
11043       *matchp = match;
11044       return 1;
11045     }
11046   if (tag1)
11047     {
11048       match[15] = tag1_val[1];
11049       match[14] = tag1_val[0];
11050       if (proto)
11051         {
11052           match[17] = proto_val & 0xff;
11053           match[16] = proto_val >> 8;
11054         }
11055       if (cos1)
11056         match[14] |= (cos1_val & 0x7) << 5;
11057
11058       *matchp = match;
11059       return 1;
11060     }
11061   if (cos2)
11062     match[18] |= (cos2_val & 0x7) << 5;
11063   if (cos1)
11064     match[14] |= (cos1_val & 0x7) << 5;
11065   if (proto)
11066     {
11067       match[13] = proto_val & 0xff;
11068       match[12] = proto_val >> 8;
11069     }
11070
11071   *matchp = match;
11072   return 1;
11073 }
11074 #endif
11075
11076 uword
11077 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11078 {
11079   u8 **matchp = va_arg (*args, u8 **);
11080   u32 skip_n_vectors = va_arg (*args, u32);
11081   u32 match_n_vectors = va_arg (*args, u32);
11082
11083   u8 *match = 0;
11084   u8 *l2 = 0;
11085   u8 *l3 = 0;
11086   u8 *l4 = 0;
11087
11088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11089     {
11090       if (unformat (input, "hex %U", unformat_hex_string, &match))
11091         ;
11092       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11093         ;
11094       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11095         ;
11096       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11097         ;
11098       else
11099         break;
11100     }
11101
11102   if (l4 && !l3)
11103     {
11104       vec_free (match);
11105       vec_free (l2);
11106       vec_free (l4);
11107       return 0;
11108     }
11109
11110   if (match || l2 || l3 || l4)
11111     {
11112       if (l2 || l3 || l4)
11113         {
11114           /* "Win a free Ethernet header in every packet" */
11115           if (l2 == 0)
11116             vec_validate_aligned (l2, 13, sizeof (u32x4));
11117           match = l2;
11118           if (vec_len (l3))
11119             {
11120               vec_append_aligned (match, l3, sizeof (u32x4));
11121               vec_free (l3);
11122             }
11123           if (vec_len (l4))
11124             {
11125               vec_append_aligned (match, l4, sizeof (u32x4));
11126               vec_free (l4);
11127             }
11128         }
11129
11130       /* Make sure the vector is big enough even if key is all 0's */
11131       vec_validate_aligned
11132         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11133          sizeof (u32x4));
11134
11135       /* Set size, include skipped vectors */
11136       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11137
11138       *matchp = match;
11139
11140       return 1;
11141     }
11142
11143   return 0;
11144 }
11145
11146 static int
11147 api_classify_add_del_session (vat_main_t * vam)
11148 {
11149   unformat_input_t *i = vam->input;
11150   vl_api_classify_add_del_session_t *mp;
11151   int is_add = 1;
11152   u32 table_index = ~0;
11153   u32 hit_next_index = ~0;
11154   u32 opaque_index = ~0;
11155   u8 *match = 0;
11156   i32 advance = 0;
11157   u32 skip_n_vectors = 0;
11158   u32 match_n_vectors = 0;
11159   u32 action = 0;
11160   u32 metadata = 0;
11161   int ret;
11162
11163   /*
11164    * Warning: you have to supply skip_n and match_n
11165    * because the API client cant simply look at the classify
11166    * table object.
11167    */
11168
11169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11170     {
11171       if (unformat (i, "del"))
11172         is_add = 0;
11173       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11174                          &hit_next_index))
11175         ;
11176       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11177                          &hit_next_index))
11178         ;
11179       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11180                          &hit_next_index))
11181         ;
11182       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11183         ;
11184       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11185         ;
11186       else if (unformat (i, "opaque-index %d", &opaque_index))
11187         ;
11188       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11189         ;
11190       else if (unformat (i, "match_n %d", &match_n_vectors))
11191         ;
11192       else if (unformat (i, "match %U", api_unformat_classify_match,
11193                          &match, skip_n_vectors, match_n_vectors))
11194         ;
11195       else if (unformat (i, "advance %d", &advance))
11196         ;
11197       else if (unformat (i, "table-index %d", &table_index))
11198         ;
11199       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11200         action = 1;
11201       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11202         action = 2;
11203       else if (unformat (i, "action %d", &action))
11204         ;
11205       else if (unformat (i, "metadata %d", &metadata))
11206         ;
11207       else
11208         break;
11209     }
11210
11211   if (table_index == ~0)
11212     {
11213       errmsg ("Table index required");
11214       return -99;
11215     }
11216
11217   if (is_add && match == 0)
11218     {
11219       errmsg ("Match value required");
11220       return -99;
11221     }
11222
11223   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11224
11225   mp->is_add = is_add;
11226   mp->table_index = ntohl (table_index);
11227   mp->hit_next_index = ntohl (hit_next_index);
11228   mp->opaque_index = ntohl (opaque_index);
11229   mp->advance = ntohl (advance);
11230   mp->action = action;
11231   mp->metadata = ntohl (metadata);
11232   clib_memcpy (mp->match, match, vec_len (match));
11233   vec_free (match);
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240 static int
11241 api_classify_set_interface_ip_table (vat_main_t * vam)
11242 {
11243   unformat_input_t *i = vam->input;
11244   vl_api_classify_set_interface_ip_table_t *mp;
11245   u32 sw_if_index;
11246   int sw_if_index_set;
11247   u32 table_index = ~0;
11248   u8 is_ipv6 = 0;
11249   int ret;
11250
11251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11252     {
11253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11254         sw_if_index_set = 1;
11255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11256         sw_if_index_set = 1;
11257       else if (unformat (i, "table %d", &table_index))
11258         ;
11259       else
11260         {
11261           clib_warning ("parse error '%U'", format_unformat_error, i);
11262           return -99;
11263         }
11264     }
11265
11266   if (sw_if_index_set == 0)
11267     {
11268       errmsg ("missing interface name or sw_if_index");
11269       return -99;
11270     }
11271
11272
11273   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11274
11275   mp->sw_if_index = ntohl (sw_if_index);
11276   mp->table_index = ntohl (table_index);
11277   mp->is_ipv6 = is_ipv6;
11278
11279   S (mp);
11280   W (ret);
11281   return ret;
11282 }
11283
11284 static int
11285 api_classify_set_interface_l2_tables (vat_main_t * vam)
11286 {
11287   unformat_input_t *i = vam->input;
11288   vl_api_classify_set_interface_l2_tables_t *mp;
11289   u32 sw_if_index;
11290   int sw_if_index_set;
11291   u32 ip4_table_index = ~0;
11292   u32 ip6_table_index = ~0;
11293   u32 other_table_index = ~0;
11294   u32 is_input = 1;
11295   int ret;
11296
11297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11300         sw_if_index_set = 1;
11301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11302         sw_if_index_set = 1;
11303       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11304         ;
11305       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11306         ;
11307       else if (unformat (i, "other-table %d", &other_table_index))
11308         ;
11309       else if (unformat (i, "is-input %d", &is_input))
11310         ;
11311       else
11312         {
11313           clib_warning ("parse error '%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   if (sw_if_index_set == 0)
11319     {
11320       errmsg ("missing interface name or sw_if_index");
11321       return -99;
11322     }
11323
11324
11325   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11326
11327   mp->sw_if_index = ntohl (sw_if_index);
11328   mp->ip4_table_index = ntohl (ip4_table_index);
11329   mp->ip6_table_index = ntohl (ip6_table_index);
11330   mp->other_table_index = ntohl (other_table_index);
11331   mp->is_input = (u8) is_input;
11332
11333   S (mp);
11334   W (ret);
11335   return ret;
11336 }
11337
11338 static int
11339 api_set_ipfix_exporter (vat_main_t * vam)
11340 {
11341   unformat_input_t *i = vam->input;
11342   vl_api_set_ipfix_exporter_t *mp;
11343   ip4_address_t collector_address;
11344   u8 collector_address_set = 0;
11345   u32 collector_port = ~0;
11346   ip4_address_t src_address;
11347   u8 src_address_set = 0;
11348   u32 vrf_id = ~0;
11349   u32 path_mtu = ~0;
11350   u32 template_interval = ~0;
11351   u8 udp_checksum = 0;
11352   int ret;
11353
11354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355     {
11356       if (unformat (i, "collector_address %U", unformat_ip4_address,
11357                     &collector_address))
11358         collector_address_set = 1;
11359       else if (unformat (i, "collector_port %d", &collector_port))
11360         ;
11361       else if (unformat (i, "src_address %U", unformat_ip4_address,
11362                          &src_address))
11363         src_address_set = 1;
11364       else if (unformat (i, "vrf_id %d", &vrf_id))
11365         ;
11366       else if (unformat (i, "path_mtu %d", &path_mtu))
11367         ;
11368       else if (unformat (i, "template_interval %d", &template_interval))
11369         ;
11370       else if (unformat (i, "udp_checksum"))
11371         udp_checksum = 1;
11372       else
11373         break;
11374     }
11375
11376   if (collector_address_set == 0)
11377     {
11378       errmsg ("collector_address required");
11379       return -99;
11380     }
11381
11382   if (src_address_set == 0)
11383     {
11384       errmsg ("src_address required");
11385       return -99;
11386     }
11387
11388   M (SET_IPFIX_EXPORTER, mp);
11389
11390   memcpy (mp->collector_address, collector_address.data,
11391           sizeof (collector_address.data));
11392   mp->collector_port = htons ((u16) collector_port);
11393   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11394   mp->vrf_id = htonl (vrf_id);
11395   mp->path_mtu = htonl (path_mtu);
11396   mp->template_interval = htonl (template_interval);
11397   mp->udp_checksum = udp_checksum;
11398
11399   S (mp);
11400   W (ret);
11401   return ret;
11402 }
11403
11404 static int
11405 api_set_ipfix_classify_stream (vat_main_t * vam)
11406 {
11407   unformat_input_t *i = vam->input;
11408   vl_api_set_ipfix_classify_stream_t *mp;
11409   u32 domain_id = 0;
11410   u32 src_port = UDP_DST_PORT_ipfix;
11411   int ret;
11412
11413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11414     {
11415       if (unformat (i, "domain %d", &domain_id))
11416         ;
11417       else if (unformat (i, "src_port %d", &src_port))
11418         ;
11419       else
11420         {
11421           errmsg ("unknown input `%U'", format_unformat_error, i);
11422           return -99;
11423         }
11424     }
11425
11426   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11427
11428   mp->domain_id = htonl (domain_id);
11429   mp->src_port = htons ((u16) src_port);
11430
11431   S (mp);
11432   W (ret);
11433   return ret;
11434 }
11435
11436 static int
11437 api_ipfix_classify_table_add_del (vat_main_t * vam)
11438 {
11439   unformat_input_t *i = vam->input;
11440   vl_api_ipfix_classify_table_add_del_t *mp;
11441   int is_add = -1;
11442   u32 classify_table_index = ~0;
11443   u8 ip_version = 0;
11444   u8 transport_protocol = 255;
11445   int ret;
11446
11447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11448     {
11449       if (unformat (i, "add"))
11450         is_add = 1;
11451       else if (unformat (i, "del"))
11452         is_add = 0;
11453       else if (unformat (i, "table %d", &classify_table_index))
11454         ;
11455       else if (unformat (i, "ip4"))
11456         ip_version = 4;
11457       else if (unformat (i, "ip6"))
11458         ip_version = 6;
11459       else if (unformat (i, "tcp"))
11460         transport_protocol = 6;
11461       else if (unformat (i, "udp"))
11462         transport_protocol = 17;
11463       else
11464         {
11465           errmsg ("unknown input `%U'", format_unformat_error, i);
11466           return -99;
11467         }
11468     }
11469
11470   if (is_add == -1)
11471     {
11472       errmsg ("expecting: add|del");
11473       return -99;
11474     }
11475   if (classify_table_index == ~0)
11476     {
11477       errmsg ("classifier table not specified");
11478       return -99;
11479     }
11480   if (ip_version == 0)
11481     {
11482       errmsg ("IP version not specified");
11483       return -99;
11484     }
11485
11486   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11487
11488   mp->is_add = is_add;
11489   mp->table_id = htonl (classify_table_index);
11490   mp->ip_version = ip_version;
11491   mp->transport_protocol = transport_protocol;
11492
11493   S (mp);
11494   W (ret);
11495   return ret;
11496 }
11497
11498 static int
11499 api_get_node_index (vat_main_t * vam)
11500 {
11501   unformat_input_t *i = vam->input;
11502   vl_api_get_node_index_t *mp;
11503   u8 *name = 0;
11504   int ret;
11505
11506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11507     {
11508       if (unformat (i, "node %s", &name))
11509         ;
11510       else
11511         break;
11512     }
11513   if (name == 0)
11514     {
11515       errmsg ("node name required");
11516       return -99;
11517     }
11518   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11519     {
11520       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11521       return -99;
11522     }
11523
11524   M (GET_NODE_INDEX, mp);
11525   clib_memcpy (mp->node_name, name, vec_len (name));
11526   vec_free (name);
11527
11528   S (mp);
11529   W (ret);
11530   return ret;
11531 }
11532
11533 static int
11534 api_get_next_index (vat_main_t * vam)
11535 {
11536   unformat_input_t *i = vam->input;
11537   vl_api_get_next_index_t *mp;
11538   u8 *node_name = 0, *next_node_name = 0;
11539   int ret;
11540
11541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (i, "node-name %s", &node_name))
11544         ;
11545       else if (unformat (i, "next-node-name %s", &next_node_name))
11546         break;
11547     }
11548
11549   if (node_name == 0)
11550     {
11551       errmsg ("node name required");
11552       return -99;
11553     }
11554   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11555     {
11556       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11557       return -99;
11558     }
11559
11560   if (next_node_name == 0)
11561     {
11562       errmsg ("next node name required");
11563       return -99;
11564     }
11565   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11566     {
11567       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11568       return -99;
11569     }
11570
11571   M (GET_NEXT_INDEX, mp);
11572   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11573   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11574   vec_free (node_name);
11575   vec_free (next_node_name);
11576
11577   S (mp);
11578   W (ret);
11579   return ret;
11580 }
11581
11582 static int
11583 api_add_node_next (vat_main_t * vam)
11584 {
11585   unformat_input_t *i = vam->input;
11586   vl_api_add_node_next_t *mp;
11587   u8 *name = 0;
11588   u8 *next = 0;
11589   int ret;
11590
11591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11592     {
11593       if (unformat (i, "node %s", &name))
11594         ;
11595       else if (unformat (i, "next %s", &next))
11596         ;
11597       else
11598         break;
11599     }
11600   if (name == 0)
11601     {
11602       errmsg ("node name required");
11603       return -99;
11604     }
11605   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11606     {
11607       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11608       return -99;
11609     }
11610   if (next == 0)
11611     {
11612       errmsg ("next node required");
11613       return -99;
11614     }
11615   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11616     {
11617       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11618       return -99;
11619     }
11620
11621   M (ADD_NODE_NEXT, mp);
11622   clib_memcpy (mp->node_name, name, vec_len (name));
11623   clib_memcpy (mp->next_name, next, vec_len (next));
11624   vec_free (name);
11625   vec_free (next);
11626
11627   S (mp);
11628   W (ret);
11629   return ret;
11630 }
11631
11632 static int
11633 api_l2tpv3_create_tunnel (vat_main_t * vam)
11634 {
11635   unformat_input_t *i = vam->input;
11636   ip6_address_t client_address, our_address;
11637   int client_address_set = 0;
11638   int our_address_set = 0;
11639   u32 local_session_id = 0;
11640   u32 remote_session_id = 0;
11641   u64 local_cookie = 0;
11642   u64 remote_cookie = 0;
11643   u8 l2_sublayer_present = 0;
11644   vl_api_l2tpv3_create_tunnel_t *mp;
11645   int ret;
11646
11647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11648     {
11649       if (unformat (i, "client_address %U", unformat_ip6_address,
11650                     &client_address))
11651         client_address_set = 1;
11652       else if (unformat (i, "our_address %U", unformat_ip6_address,
11653                          &our_address))
11654         our_address_set = 1;
11655       else if (unformat (i, "local_session_id %d", &local_session_id))
11656         ;
11657       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11658         ;
11659       else if (unformat (i, "local_cookie %lld", &local_cookie))
11660         ;
11661       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11662         ;
11663       else if (unformat (i, "l2-sublayer-present"))
11664         l2_sublayer_present = 1;
11665       else
11666         break;
11667     }
11668
11669   if (client_address_set == 0)
11670     {
11671       errmsg ("client_address required");
11672       return -99;
11673     }
11674
11675   if (our_address_set == 0)
11676     {
11677       errmsg ("our_address required");
11678       return -99;
11679     }
11680
11681   M (L2TPV3_CREATE_TUNNEL, mp);
11682
11683   clib_memcpy (mp->client_address, client_address.as_u8,
11684                sizeof (mp->client_address));
11685
11686   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11687
11688   mp->local_session_id = ntohl (local_session_id);
11689   mp->remote_session_id = ntohl (remote_session_id);
11690   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11691   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11692   mp->l2_sublayer_present = l2_sublayer_present;
11693   mp->is_ipv6 = 1;
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   u32 sw_if_index;
11705   u8 sw_if_index_set = 0;
11706   u64 new_local_cookie = 0;
11707   u64 new_remote_cookie = 0;
11708   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11718         ;
11719       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11720         ;
11721       else
11722         break;
11723     }
11724
11725   if (sw_if_index_set == 0)
11726     {
11727       errmsg ("missing interface name or sw_if_index");
11728       return -99;
11729     }
11730
11731   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11732
11733   mp->sw_if_index = ntohl (sw_if_index);
11734   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11735   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11736
11737   S (mp);
11738   W (ret);
11739   return ret;
11740 }
11741
11742 static int
11743 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11744 {
11745   unformat_input_t *i = vam->input;
11746   vl_api_l2tpv3_interface_enable_disable_t *mp;
11747   u32 sw_if_index;
11748   u8 sw_if_index_set = 0;
11749   u8 enable_disable = 1;
11750   int ret;
11751
11752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11753     {
11754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11755         sw_if_index_set = 1;
11756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11757         sw_if_index_set = 1;
11758       else if (unformat (i, "enable"))
11759         enable_disable = 1;
11760       else if (unformat (i, "disable"))
11761         enable_disable = 0;
11762       else
11763         break;
11764     }
11765
11766   if (sw_if_index_set == 0)
11767     {
11768       errmsg ("missing interface name or sw_if_index");
11769       return -99;
11770     }
11771
11772   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11773
11774   mp->sw_if_index = ntohl (sw_if_index);
11775   mp->enable_disable = enable_disable;
11776
11777   S (mp);
11778   W (ret);
11779   return ret;
11780 }
11781
11782 static int
11783 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11784 {
11785   unformat_input_t *i = vam->input;
11786   vl_api_l2tpv3_set_lookup_key_t *mp;
11787   u8 key = ~0;
11788   int ret;
11789
11790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11791     {
11792       if (unformat (i, "lookup_v6_src"))
11793         key = L2T_LOOKUP_SRC_ADDRESS;
11794       else if (unformat (i, "lookup_v6_dst"))
11795         key = L2T_LOOKUP_DST_ADDRESS;
11796       else if (unformat (i, "lookup_session_id"))
11797         key = L2T_LOOKUP_SESSION_ID;
11798       else
11799         break;
11800     }
11801
11802   if (key == (u8) ~ 0)
11803     {
11804       errmsg ("l2tp session lookup key unset");
11805       return -99;
11806     }
11807
11808   M (L2TPV3_SET_LOOKUP_KEY, mp);
11809
11810   mp->key = key;
11811
11812   S (mp);
11813   W (ret);
11814   return ret;
11815 }
11816
11817 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11818   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11819 {
11820   vat_main_t *vam = &vat_main;
11821
11822   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11823          format_ip6_address, mp->our_address,
11824          format_ip6_address, mp->client_address,
11825          clib_net_to_host_u32 (mp->sw_if_index));
11826
11827   print (vam->ofp,
11828          "   local cookies %016llx %016llx remote cookie %016llx",
11829          clib_net_to_host_u64 (mp->local_cookie[0]),
11830          clib_net_to_host_u64 (mp->local_cookie[1]),
11831          clib_net_to_host_u64 (mp->remote_cookie));
11832
11833   print (vam->ofp, "   local session-id %d remote session-id %d",
11834          clib_net_to_host_u32 (mp->local_session_id),
11835          clib_net_to_host_u32 (mp->remote_session_id));
11836
11837   print (vam->ofp, "   l2 specific sublayer %s\n",
11838          mp->l2_sublayer_present ? "preset" : "absent");
11839
11840 }
11841
11842 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11843   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11844 {
11845   vat_main_t *vam = &vat_main;
11846   vat_json_node_t *node = NULL;
11847   struct in6_addr addr;
11848
11849   if (VAT_JSON_ARRAY != vam->json_tree.type)
11850     {
11851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11852       vat_json_init_array (&vam->json_tree);
11853     }
11854   node = vat_json_array_add (&vam->json_tree);
11855
11856   vat_json_init_object (node);
11857
11858   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11859   vat_json_object_add_ip6 (node, "our_address", addr);
11860   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11861   vat_json_object_add_ip6 (node, "client_address", addr);
11862
11863   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11864   vat_json_init_array (lc);
11865   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11866   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11867   vat_json_object_add_uint (node, "remote_cookie",
11868                             clib_net_to_host_u64 (mp->remote_cookie));
11869
11870   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11871   vat_json_object_add_uint (node, "local_session_id",
11872                             clib_net_to_host_u32 (mp->local_session_id));
11873   vat_json_object_add_uint (node, "remote_session_id",
11874                             clib_net_to_host_u32 (mp->remote_session_id));
11875   vat_json_object_add_string_copy (node, "l2_sublayer",
11876                                    mp->l2_sublayer_present ? (u8 *) "present"
11877                                    : (u8 *) "absent");
11878 }
11879
11880 static int
11881 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11882 {
11883   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11884   vl_api_control_ping_t *mp_ping;
11885   int ret;
11886
11887   /* Get list of l2tpv3-tunnel interfaces */
11888   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11889   S (mp);
11890
11891   /* Use a control ping for synchronization */
11892   MPING (CONTROL_PING, mp_ping);
11893   S (mp_ping);
11894
11895   W (ret);
11896   return ret;
11897 }
11898
11899
11900 static void vl_api_sw_interface_tap_details_t_handler
11901   (vl_api_sw_interface_tap_details_t * mp)
11902 {
11903   vat_main_t *vam = &vat_main;
11904
11905   print (vam->ofp, "%-16s %d",
11906          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11907 }
11908
11909 static void vl_api_sw_interface_tap_details_t_handler_json
11910   (vl_api_sw_interface_tap_details_t * mp)
11911 {
11912   vat_main_t *vam = &vat_main;
11913   vat_json_node_t *node = NULL;
11914
11915   if (VAT_JSON_ARRAY != vam->json_tree.type)
11916     {
11917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11918       vat_json_init_array (&vam->json_tree);
11919     }
11920   node = vat_json_array_add (&vam->json_tree);
11921
11922   vat_json_init_object (node);
11923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11924   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11925 }
11926
11927 static int
11928 api_sw_interface_tap_dump (vat_main_t * vam)
11929 {
11930   vl_api_sw_interface_tap_dump_t *mp;
11931   vl_api_control_ping_t *mp_ping;
11932   int ret;
11933
11934   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11935   /* Get list of tap interfaces */
11936   M (SW_INTERFACE_TAP_DUMP, mp);
11937   S (mp);
11938
11939   /* Use a control ping for synchronization */
11940   MPING (CONTROL_PING, mp_ping);
11941   S (mp_ping);
11942
11943   W (ret);
11944   return ret;
11945 }
11946
11947 static uword unformat_vxlan_decap_next
11948   (unformat_input_t * input, va_list * args)
11949 {
11950   u32 *result = va_arg (*args, u32 *);
11951   u32 tmp;
11952
11953   if (unformat (input, "l2"))
11954     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11955   else if (unformat (input, "%d", &tmp))
11956     *result = tmp;
11957   else
11958     return 0;
11959   return 1;
11960 }
11961
11962 static int
11963 api_vxlan_add_del_tunnel (vat_main_t * vam)
11964 {
11965   unformat_input_t *line_input = vam->input;
11966   vl_api_vxlan_add_del_tunnel_t *mp;
11967   ip46_address_t src, dst;
11968   u8 is_add = 1;
11969   u8 ipv4_set = 0, ipv6_set = 0;
11970   u8 src_set = 0;
11971   u8 dst_set = 0;
11972   u8 grp_set = 0;
11973   u32 mcast_sw_if_index = ~0;
11974   u32 encap_vrf_id = 0;
11975   u32 decap_next_index = ~0;
11976   u32 vni = 0;
11977   int ret;
11978
11979   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11980   memset (&src, 0, sizeof src);
11981   memset (&dst, 0, sizeof dst);
11982
11983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11984     {
11985       if (unformat (line_input, "del"))
11986         is_add = 0;
11987       else
11988         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11989         {
11990           ipv4_set = 1;
11991           src_set = 1;
11992         }
11993       else
11994         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11995         {
11996           ipv4_set = 1;
11997           dst_set = 1;
11998         }
11999       else
12000         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12001         {
12002           ipv6_set = 1;
12003           src_set = 1;
12004         }
12005       else
12006         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12007         {
12008           ipv6_set = 1;
12009           dst_set = 1;
12010         }
12011       else if (unformat (line_input, "group %U %U",
12012                          unformat_ip4_address, &dst.ip4,
12013                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12014         {
12015           grp_set = dst_set = 1;
12016           ipv4_set = 1;
12017         }
12018       else if (unformat (line_input, "group %U",
12019                          unformat_ip4_address, &dst.ip4))
12020         {
12021           grp_set = dst_set = 1;
12022           ipv4_set = 1;
12023         }
12024       else if (unformat (line_input, "group %U %U",
12025                          unformat_ip6_address, &dst.ip6,
12026                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12027         {
12028           grp_set = dst_set = 1;
12029           ipv6_set = 1;
12030         }
12031       else if (unformat (line_input, "group %U",
12032                          unformat_ip6_address, &dst.ip6))
12033         {
12034           grp_set = dst_set = 1;
12035           ipv6_set = 1;
12036         }
12037       else
12038         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12039         ;
12040       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12041         ;
12042       else if (unformat (line_input, "decap-next %U",
12043                          unformat_vxlan_decap_next, &decap_next_index))
12044         ;
12045       else if (unformat (line_input, "vni %d", &vni))
12046         ;
12047       else
12048         {
12049           errmsg ("parse error '%U'", format_unformat_error, line_input);
12050           return -99;
12051         }
12052     }
12053
12054   if (src_set == 0)
12055     {
12056       errmsg ("tunnel src address not specified");
12057       return -99;
12058     }
12059   if (dst_set == 0)
12060     {
12061       errmsg ("tunnel dst address not specified");
12062       return -99;
12063     }
12064
12065   if (grp_set && !ip46_address_is_multicast (&dst))
12066     {
12067       errmsg ("tunnel group address not multicast");
12068       return -99;
12069     }
12070   if (grp_set && mcast_sw_if_index == ~0)
12071     {
12072       errmsg ("tunnel nonexistent multicast device");
12073       return -99;
12074     }
12075   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12076     {
12077       errmsg ("tunnel dst address must be unicast");
12078       return -99;
12079     }
12080
12081
12082   if (ipv4_set && ipv6_set)
12083     {
12084       errmsg ("both IPv4 and IPv6 addresses specified");
12085       return -99;
12086     }
12087
12088   if ((vni == 0) || (vni >> 24))
12089     {
12090       errmsg ("vni not specified or out of range");
12091       return -99;
12092     }
12093
12094   M (VXLAN_ADD_DEL_TUNNEL, mp);
12095
12096   if (ipv6_set)
12097     {
12098       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12099       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12100     }
12101   else
12102     {
12103       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12104       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12105     }
12106   mp->encap_vrf_id = ntohl (encap_vrf_id);
12107   mp->decap_next_index = ntohl (decap_next_index);
12108   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12109   mp->vni = ntohl (vni);
12110   mp->is_add = is_add;
12111   mp->is_ipv6 = ipv6_set;
12112
12113   S (mp);
12114   W (ret);
12115   return ret;
12116 }
12117
12118 static void vl_api_vxlan_tunnel_details_t_handler
12119   (vl_api_vxlan_tunnel_details_t * mp)
12120 {
12121   vat_main_t *vam = &vat_main;
12122   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12123   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12124
12125   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12126          ntohl (mp->sw_if_index),
12127          format_ip46_address, &src, IP46_TYPE_ANY,
12128          format_ip46_address, &dst, IP46_TYPE_ANY,
12129          ntohl (mp->encap_vrf_id),
12130          ntohl (mp->decap_next_index), ntohl (mp->vni),
12131          ntohl (mp->mcast_sw_if_index));
12132 }
12133
12134 static void vl_api_vxlan_tunnel_details_t_handler_json
12135   (vl_api_vxlan_tunnel_details_t * mp)
12136 {
12137   vat_main_t *vam = &vat_main;
12138   vat_json_node_t *node = NULL;
12139
12140   if (VAT_JSON_ARRAY != vam->json_tree.type)
12141     {
12142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12143       vat_json_init_array (&vam->json_tree);
12144     }
12145   node = vat_json_array_add (&vam->json_tree);
12146
12147   vat_json_init_object (node);
12148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12149   if (mp->is_ipv6)
12150     {
12151       struct in6_addr ip6;
12152
12153       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12154       vat_json_object_add_ip6 (node, "src_address", ip6);
12155       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12156       vat_json_object_add_ip6 (node, "dst_address", ip6);
12157     }
12158   else
12159     {
12160       struct in_addr ip4;
12161
12162       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12163       vat_json_object_add_ip4 (node, "src_address", ip4);
12164       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12165       vat_json_object_add_ip4 (node, "dst_address", ip4);
12166     }
12167   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12168   vat_json_object_add_uint (node, "decap_next_index",
12169                             ntohl (mp->decap_next_index));
12170   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12171   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12172   vat_json_object_add_uint (node, "mcast_sw_if_index",
12173                             ntohl (mp->mcast_sw_if_index));
12174 }
12175
12176 static int
12177 api_vxlan_tunnel_dump (vat_main_t * vam)
12178 {
12179   unformat_input_t *i = vam->input;
12180   vl_api_vxlan_tunnel_dump_t *mp;
12181   vl_api_control_ping_t *mp_ping;
12182   u32 sw_if_index;
12183   u8 sw_if_index_set = 0;
12184   int ret;
12185
12186   /* Parse args required to build the message */
12187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (i, "sw_if_index %d", &sw_if_index))
12190         sw_if_index_set = 1;
12191       else
12192         break;
12193     }
12194
12195   if (sw_if_index_set == 0)
12196     {
12197       sw_if_index = ~0;
12198     }
12199
12200   if (!vam->json_output)
12201     {
12202       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12203              "sw_if_index", "src_address", "dst_address",
12204              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12205     }
12206
12207   /* Get list of vxlan-tunnel interfaces */
12208   M (VXLAN_TUNNEL_DUMP, mp);
12209
12210   mp->sw_if_index = htonl (sw_if_index);
12211
12212   S (mp);
12213
12214   /* Use a control ping for synchronization */
12215   MPING (CONTROL_PING, mp_ping);
12216   S (mp_ping);
12217
12218   W (ret);
12219   return ret;
12220 }
12221
12222 static uword unformat_geneve_decap_next
12223   (unformat_input_t * input, va_list * args)
12224 {
12225   u32 *result = va_arg (*args, u32 *);
12226   u32 tmp;
12227
12228   if (unformat (input, "l2"))
12229     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12230   else if (unformat (input, "%d", &tmp))
12231     *result = tmp;
12232   else
12233     return 0;
12234   return 1;
12235 }
12236
12237 static int
12238 api_geneve_add_del_tunnel (vat_main_t * vam)
12239 {
12240   unformat_input_t *line_input = vam->input;
12241   vl_api_geneve_add_del_tunnel_t *mp;
12242   ip46_address_t src, dst;
12243   u8 is_add = 1;
12244   u8 ipv4_set = 0, ipv6_set = 0;
12245   u8 src_set = 0;
12246   u8 dst_set = 0;
12247   u8 grp_set = 0;
12248   u32 mcast_sw_if_index = ~0;
12249   u32 encap_vrf_id = 0;
12250   u32 decap_next_index = ~0;
12251   u32 vni = 0;
12252   int ret;
12253
12254   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12255   memset (&src, 0, sizeof src);
12256   memset (&dst, 0, sizeof dst);
12257
12258   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (line_input, "del"))
12261         is_add = 0;
12262       else
12263         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12264         {
12265           ipv4_set = 1;
12266           src_set = 1;
12267         }
12268       else
12269         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12270         {
12271           ipv4_set = 1;
12272           dst_set = 1;
12273         }
12274       else
12275         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12276         {
12277           ipv6_set = 1;
12278           src_set = 1;
12279         }
12280       else
12281         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12282         {
12283           ipv6_set = 1;
12284           dst_set = 1;
12285         }
12286       else if (unformat (line_input, "group %U %U",
12287                          unformat_ip4_address, &dst.ip4,
12288                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12289         {
12290           grp_set = dst_set = 1;
12291           ipv4_set = 1;
12292         }
12293       else if (unformat (line_input, "group %U",
12294                          unformat_ip4_address, &dst.ip4))
12295         {
12296           grp_set = dst_set = 1;
12297           ipv4_set = 1;
12298         }
12299       else if (unformat (line_input, "group %U %U",
12300                          unformat_ip6_address, &dst.ip6,
12301                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12302         {
12303           grp_set = dst_set = 1;
12304           ipv6_set = 1;
12305         }
12306       else if (unformat (line_input, "group %U",
12307                          unformat_ip6_address, &dst.ip6))
12308         {
12309           grp_set = dst_set = 1;
12310           ipv6_set = 1;
12311         }
12312       else
12313         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12314         ;
12315       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12316         ;
12317       else if (unformat (line_input, "decap-next %U",
12318                          unformat_geneve_decap_next, &decap_next_index))
12319         ;
12320       else if (unformat (line_input, "vni %d", &vni))
12321         ;
12322       else
12323         {
12324           errmsg ("parse error '%U'", format_unformat_error, line_input);
12325           return -99;
12326         }
12327     }
12328
12329   if (src_set == 0)
12330     {
12331       errmsg ("tunnel src address not specified");
12332       return -99;
12333     }
12334   if (dst_set == 0)
12335     {
12336       errmsg ("tunnel dst address not specified");
12337       return -99;
12338     }
12339
12340   if (grp_set && !ip46_address_is_multicast (&dst))
12341     {
12342       errmsg ("tunnel group address not multicast");
12343       return -99;
12344     }
12345   if (grp_set && mcast_sw_if_index == ~0)
12346     {
12347       errmsg ("tunnel nonexistent multicast device");
12348       return -99;
12349     }
12350   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12351     {
12352       errmsg ("tunnel dst address must be unicast");
12353       return -99;
12354     }
12355
12356
12357   if (ipv4_set && ipv6_set)
12358     {
12359       errmsg ("both IPv4 and IPv6 addresses specified");
12360       return -99;
12361     }
12362
12363   if ((vni == 0) || (vni >> 24))
12364     {
12365       errmsg ("vni not specified or out of range");
12366       return -99;
12367     }
12368
12369   M (GENEVE_ADD_DEL_TUNNEL, mp);
12370
12371   if (ipv6_set)
12372     {
12373       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12374       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12375     }
12376   else
12377     {
12378       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12379       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12380     }
12381   mp->encap_vrf_id = ntohl (encap_vrf_id);
12382   mp->decap_next_index = ntohl (decap_next_index);
12383   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12384   mp->vni = ntohl (vni);
12385   mp->is_add = is_add;
12386   mp->is_ipv6 = ipv6_set;
12387
12388   S (mp);
12389   W (ret);
12390   return ret;
12391 }
12392
12393 static void vl_api_geneve_tunnel_details_t_handler
12394   (vl_api_geneve_tunnel_details_t * mp)
12395 {
12396   vat_main_t *vam = &vat_main;
12397   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12398   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12399
12400   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12401          ntohl (mp->sw_if_index),
12402          format_ip46_address, &src, IP46_TYPE_ANY,
12403          format_ip46_address, &dst, IP46_TYPE_ANY,
12404          ntohl (mp->encap_vrf_id),
12405          ntohl (mp->decap_next_index), ntohl (mp->vni),
12406          ntohl (mp->mcast_sw_if_index));
12407 }
12408
12409 static void vl_api_geneve_tunnel_details_t_handler_json
12410   (vl_api_geneve_tunnel_details_t * mp)
12411 {
12412   vat_main_t *vam = &vat_main;
12413   vat_json_node_t *node = NULL;
12414
12415   if (VAT_JSON_ARRAY != vam->json_tree.type)
12416     {
12417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12418       vat_json_init_array (&vam->json_tree);
12419     }
12420   node = vat_json_array_add (&vam->json_tree);
12421
12422   vat_json_init_object (node);
12423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12424   if (mp->is_ipv6)
12425     {
12426       struct in6_addr ip6;
12427
12428       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12429       vat_json_object_add_ip6 (node, "src_address", ip6);
12430       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12431       vat_json_object_add_ip6 (node, "dst_address", ip6);
12432     }
12433   else
12434     {
12435       struct in_addr ip4;
12436
12437       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12438       vat_json_object_add_ip4 (node, "src_address", ip4);
12439       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12440       vat_json_object_add_ip4 (node, "dst_address", ip4);
12441     }
12442   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12443   vat_json_object_add_uint (node, "decap_next_index",
12444                             ntohl (mp->decap_next_index));
12445   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12446   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12447   vat_json_object_add_uint (node, "mcast_sw_if_index",
12448                             ntohl (mp->mcast_sw_if_index));
12449 }
12450
12451 static int
12452 api_geneve_tunnel_dump (vat_main_t * vam)
12453 {
12454   unformat_input_t *i = vam->input;
12455   vl_api_geneve_tunnel_dump_t *mp;
12456   vl_api_control_ping_t *mp_ping;
12457   u32 sw_if_index;
12458   u8 sw_if_index_set = 0;
12459   int ret;
12460
12461   /* Parse args required to build the message */
12462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12463     {
12464       if (unformat (i, "sw_if_index %d", &sw_if_index))
12465         sw_if_index_set = 1;
12466       else
12467         break;
12468     }
12469
12470   if (sw_if_index_set == 0)
12471     {
12472       sw_if_index = ~0;
12473     }
12474
12475   if (!vam->json_output)
12476     {
12477       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12478              "sw_if_index", "local_address", "remote_address",
12479              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12480     }
12481
12482   /* Get list of geneve-tunnel interfaces */
12483   M (GENEVE_TUNNEL_DUMP, mp);
12484
12485   mp->sw_if_index = htonl (sw_if_index);
12486
12487   S (mp);
12488
12489   /* Use a control ping for synchronization */
12490   M (CONTROL_PING, mp_ping);
12491   S (mp_ping);
12492
12493   W (ret);
12494   return ret;
12495 }
12496
12497 static int
12498 api_gre_add_del_tunnel (vat_main_t * vam)
12499 {
12500   unformat_input_t *line_input = vam->input;
12501   vl_api_gre_add_del_tunnel_t *mp;
12502   ip4_address_t src4, dst4;
12503   ip6_address_t src6, dst6;
12504   u8 is_add = 1;
12505   u8 ipv4_set = 0;
12506   u8 ipv6_set = 0;
12507   u8 teb = 0;
12508   u8 src_set = 0;
12509   u8 dst_set = 0;
12510   u32 outer_fib_id = 0;
12511   int ret;
12512
12513   memset (&src4, 0, sizeof src4);
12514   memset (&dst4, 0, sizeof dst4);
12515   memset (&src6, 0, sizeof src6);
12516   memset (&dst6, 0, sizeof dst6);
12517
12518   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12519     {
12520       if (unformat (line_input, "del"))
12521         is_add = 0;
12522       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12523         {
12524           src_set = 1;
12525           ipv4_set = 1;
12526         }
12527       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12528         {
12529           dst_set = 1;
12530           ipv4_set = 1;
12531         }
12532       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12533         {
12534           src_set = 1;
12535           ipv6_set = 1;
12536         }
12537       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12538         {
12539           dst_set = 1;
12540           ipv6_set = 1;
12541         }
12542       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12543         ;
12544       else if (unformat (line_input, "teb"))
12545         teb = 1;
12546       else
12547         {
12548           errmsg ("parse error '%U'", format_unformat_error, line_input);
12549           return -99;
12550         }
12551     }
12552
12553   if (src_set == 0)
12554     {
12555       errmsg ("tunnel src address not specified");
12556       return -99;
12557     }
12558   if (dst_set == 0)
12559     {
12560       errmsg ("tunnel dst address not specified");
12561       return -99;
12562     }
12563   if (ipv4_set && ipv6_set)
12564     {
12565       errmsg ("both IPv4 and IPv6 addresses specified");
12566       return -99;
12567     }
12568
12569
12570   M (GRE_ADD_DEL_TUNNEL, mp);
12571
12572   if (ipv4_set)
12573     {
12574       clib_memcpy (&mp->src_address, &src4, 4);
12575       clib_memcpy (&mp->dst_address, &dst4, 4);
12576     }
12577   else
12578     {
12579       clib_memcpy (&mp->src_address, &src6, 16);
12580       clib_memcpy (&mp->dst_address, &dst6, 16);
12581     }
12582   mp->outer_fib_id = ntohl (outer_fib_id);
12583   mp->is_add = is_add;
12584   mp->teb = teb;
12585   mp->is_ipv6 = ipv6_set;
12586
12587   S (mp);
12588   W (ret);
12589   return ret;
12590 }
12591
12592 static void vl_api_gre_tunnel_details_t_handler
12593   (vl_api_gre_tunnel_details_t * mp)
12594 {
12595   vat_main_t *vam = &vat_main;
12596   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12597   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12598
12599   print (vam->ofp, "%11d%24U%24U%6d%14d",
12600          ntohl (mp->sw_if_index),
12601          format_ip46_address, &src, IP46_TYPE_ANY,
12602          format_ip46_address, &dst, IP46_TYPE_ANY,
12603          mp->teb, ntohl (mp->outer_fib_id));
12604 }
12605
12606 static void vl_api_gre_tunnel_details_t_handler_json
12607   (vl_api_gre_tunnel_details_t * mp)
12608 {
12609   vat_main_t *vam = &vat_main;
12610   vat_json_node_t *node = NULL;
12611   struct in_addr ip4;
12612   struct in6_addr ip6;
12613
12614   if (VAT_JSON_ARRAY != vam->json_tree.type)
12615     {
12616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12617       vat_json_init_array (&vam->json_tree);
12618     }
12619   node = vat_json_array_add (&vam->json_tree);
12620
12621   vat_json_init_object (node);
12622   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12623   if (!mp->is_ipv6)
12624     {
12625       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12626       vat_json_object_add_ip4 (node, "src_address", ip4);
12627       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12628       vat_json_object_add_ip4 (node, "dst_address", ip4);
12629     }
12630   else
12631     {
12632       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12633       vat_json_object_add_ip6 (node, "src_address", ip6);
12634       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12635       vat_json_object_add_ip6 (node, "dst_address", ip6);
12636     }
12637   vat_json_object_add_uint (node, "teb", mp->teb);
12638   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12639   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12640 }
12641
12642 static int
12643 api_gre_tunnel_dump (vat_main_t * vam)
12644 {
12645   unformat_input_t *i = vam->input;
12646   vl_api_gre_tunnel_dump_t *mp;
12647   vl_api_control_ping_t *mp_ping;
12648   u32 sw_if_index;
12649   u8 sw_if_index_set = 0;
12650   int ret;
12651
12652   /* Parse args required to build the message */
12653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12654     {
12655       if (unformat (i, "sw_if_index %d", &sw_if_index))
12656         sw_if_index_set = 1;
12657       else
12658         break;
12659     }
12660
12661   if (sw_if_index_set == 0)
12662     {
12663       sw_if_index = ~0;
12664     }
12665
12666   if (!vam->json_output)
12667     {
12668       print (vam->ofp, "%11s%24s%24s%6s%14s",
12669              "sw_if_index", "src_address", "dst_address", "teb",
12670              "outer_fib_id");
12671     }
12672
12673   /* Get list of gre-tunnel interfaces */
12674   M (GRE_TUNNEL_DUMP, mp);
12675
12676   mp->sw_if_index = htonl (sw_if_index);
12677
12678   S (mp);
12679
12680   /* Use a control ping for synchronization */
12681   MPING (CONTROL_PING, mp_ping);
12682   S (mp_ping);
12683
12684   W (ret);
12685   return ret;
12686 }
12687
12688 static int
12689 api_l2_fib_clear_table (vat_main_t * vam)
12690 {
12691 //  unformat_input_t * i = vam->input;
12692   vl_api_l2_fib_clear_table_t *mp;
12693   int ret;
12694
12695   M (L2_FIB_CLEAR_TABLE, mp);
12696
12697   S (mp);
12698   W (ret);
12699   return ret;
12700 }
12701
12702 static int
12703 api_l2_interface_efp_filter (vat_main_t * vam)
12704 {
12705   unformat_input_t *i = vam->input;
12706   vl_api_l2_interface_efp_filter_t *mp;
12707   u32 sw_if_index;
12708   u8 enable = 1;
12709   u8 sw_if_index_set = 0;
12710   int ret;
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12715         sw_if_index_set = 1;
12716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12717         sw_if_index_set = 1;
12718       else if (unformat (i, "enable"))
12719         enable = 1;
12720       else if (unformat (i, "disable"))
12721         enable = 0;
12722       else
12723         {
12724           clib_warning ("parse error '%U'", format_unformat_error, i);
12725           return -99;
12726         }
12727     }
12728
12729   if (sw_if_index_set == 0)
12730     {
12731       errmsg ("missing sw_if_index");
12732       return -99;
12733     }
12734
12735   M (L2_INTERFACE_EFP_FILTER, mp);
12736
12737   mp->sw_if_index = ntohl (sw_if_index);
12738   mp->enable_disable = enable;
12739
12740   S (mp);
12741   W (ret);
12742   return ret;
12743 }
12744
12745 #define foreach_vtr_op                          \
12746 _("disable",  L2_VTR_DISABLED)                  \
12747 _("push-1",  L2_VTR_PUSH_1)                     \
12748 _("push-2",  L2_VTR_PUSH_2)                     \
12749 _("pop-1",  L2_VTR_POP_1)                       \
12750 _("pop-2",  L2_VTR_POP_2)                       \
12751 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12752 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12753 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12754 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12755
12756 static int
12757 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12758 {
12759   unformat_input_t *i = vam->input;
12760   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12761   u32 sw_if_index;
12762   u8 sw_if_index_set = 0;
12763   u8 vtr_op_set = 0;
12764   u32 vtr_op = 0;
12765   u32 push_dot1q = 1;
12766   u32 tag1 = ~0;
12767   u32 tag2 = ~0;
12768   int ret;
12769
12770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12771     {
12772       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12773         sw_if_index_set = 1;
12774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12775         sw_if_index_set = 1;
12776       else if (unformat (i, "vtr_op %d", &vtr_op))
12777         vtr_op_set = 1;
12778 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12779       foreach_vtr_op
12780 #undef _
12781         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12782         ;
12783       else if (unformat (i, "tag1 %d", &tag1))
12784         ;
12785       else if (unformat (i, "tag2 %d", &tag2))
12786         ;
12787       else
12788         {
12789           clib_warning ("parse error '%U'", format_unformat_error, i);
12790           return -99;
12791         }
12792     }
12793
12794   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12795     {
12796       errmsg ("missing vtr operation or sw_if_index");
12797       return -99;
12798     }
12799
12800   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12801   mp->sw_if_index = ntohl (sw_if_index);
12802   mp->vtr_op = ntohl (vtr_op);
12803   mp->push_dot1q = ntohl (push_dot1q);
12804   mp->tag1 = ntohl (tag1);
12805   mp->tag2 = ntohl (tag2);
12806
12807   S (mp);
12808   W (ret);
12809   return ret;
12810 }
12811
12812 static int
12813 api_create_vhost_user_if (vat_main_t * vam)
12814 {
12815   unformat_input_t *i = vam->input;
12816   vl_api_create_vhost_user_if_t *mp;
12817   u8 *file_name;
12818   u8 is_server = 0;
12819   u8 file_name_set = 0;
12820   u32 custom_dev_instance = ~0;
12821   u8 hwaddr[6];
12822   u8 use_custom_mac = 0;
12823   u8 *tag = 0;
12824   int ret;
12825
12826   /* Shut up coverity */
12827   memset (hwaddr, 0, sizeof (hwaddr));
12828
12829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12830     {
12831       if (unformat (i, "socket %s", &file_name))
12832         {
12833           file_name_set = 1;
12834         }
12835       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12836         ;
12837       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12838         use_custom_mac = 1;
12839       else if (unformat (i, "server"))
12840         is_server = 1;
12841       else if (unformat (i, "tag %s", &tag))
12842         ;
12843       else
12844         break;
12845     }
12846
12847   if (file_name_set == 0)
12848     {
12849       errmsg ("missing socket file name");
12850       return -99;
12851     }
12852
12853   if (vec_len (file_name) > 255)
12854     {
12855       errmsg ("socket file name too long");
12856       return -99;
12857     }
12858   vec_add1 (file_name, 0);
12859
12860   M (CREATE_VHOST_USER_IF, mp);
12861
12862   mp->is_server = is_server;
12863   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12864   vec_free (file_name);
12865   if (custom_dev_instance != ~0)
12866     {
12867       mp->renumber = 1;
12868       mp->custom_dev_instance = ntohl (custom_dev_instance);
12869     }
12870   mp->use_custom_mac = use_custom_mac;
12871   clib_memcpy (mp->mac_address, hwaddr, 6);
12872   if (tag)
12873     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12874   vec_free (tag);
12875
12876   S (mp);
12877   W (ret);
12878   return ret;
12879 }
12880
12881 static int
12882 api_modify_vhost_user_if (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_modify_vhost_user_if_t *mp;
12886   u8 *file_name;
12887   u8 is_server = 0;
12888   u8 file_name_set = 0;
12889   u32 custom_dev_instance = ~0;
12890   u8 sw_if_index_set = 0;
12891   u32 sw_if_index = (u32) ~ 0;
12892   int ret;
12893
12894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12897         sw_if_index_set = 1;
12898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12899         sw_if_index_set = 1;
12900       else if (unformat (i, "socket %s", &file_name))
12901         {
12902           file_name_set = 1;
12903         }
12904       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12905         ;
12906       else if (unformat (i, "server"))
12907         is_server = 1;
12908       else
12909         break;
12910     }
12911
12912   if (sw_if_index_set == 0)
12913     {
12914       errmsg ("missing sw_if_index or interface name");
12915       return -99;
12916     }
12917
12918   if (file_name_set == 0)
12919     {
12920       errmsg ("missing socket file name");
12921       return -99;
12922     }
12923
12924   if (vec_len (file_name) > 255)
12925     {
12926       errmsg ("socket file name too long");
12927       return -99;
12928     }
12929   vec_add1 (file_name, 0);
12930
12931   M (MODIFY_VHOST_USER_IF, mp);
12932
12933   mp->sw_if_index = ntohl (sw_if_index);
12934   mp->is_server = is_server;
12935   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12936   vec_free (file_name);
12937   if (custom_dev_instance != ~0)
12938     {
12939       mp->renumber = 1;
12940       mp->custom_dev_instance = ntohl (custom_dev_instance);
12941     }
12942
12943   S (mp);
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static int
12949 api_delete_vhost_user_if (vat_main_t * vam)
12950 {
12951   unformat_input_t *i = vam->input;
12952   vl_api_delete_vhost_user_if_t *mp;
12953   u32 sw_if_index = ~0;
12954   u8 sw_if_index_set = 0;
12955   int ret;
12956
12957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12960         sw_if_index_set = 1;
12961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12962         sw_if_index_set = 1;
12963       else
12964         break;
12965     }
12966
12967   if (sw_if_index_set == 0)
12968     {
12969       errmsg ("missing sw_if_index or interface name");
12970       return -99;
12971     }
12972
12973
12974   M (DELETE_VHOST_USER_IF, mp);
12975
12976   mp->sw_if_index = ntohl (sw_if_index);
12977
12978   S (mp);
12979   W (ret);
12980   return ret;
12981 }
12982
12983 static void vl_api_sw_interface_vhost_user_details_t_handler
12984   (vl_api_sw_interface_vhost_user_details_t * mp)
12985 {
12986   vat_main_t *vam = &vat_main;
12987
12988   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12989          (char *) mp->interface_name,
12990          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12991          clib_net_to_host_u64 (mp->features), mp->is_server,
12992          ntohl (mp->num_regions), (char *) mp->sock_filename);
12993   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12994 }
12995
12996 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12997   (vl_api_sw_interface_vhost_user_details_t * mp)
12998 {
12999   vat_main_t *vam = &vat_main;
13000   vat_json_node_t *node = NULL;
13001
13002   if (VAT_JSON_ARRAY != vam->json_tree.type)
13003     {
13004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13005       vat_json_init_array (&vam->json_tree);
13006     }
13007   node = vat_json_array_add (&vam->json_tree);
13008
13009   vat_json_init_object (node);
13010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13011   vat_json_object_add_string_copy (node, "interface_name",
13012                                    mp->interface_name);
13013   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13014                             ntohl (mp->virtio_net_hdr_sz));
13015   vat_json_object_add_uint (node, "features",
13016                             clib_net_to_host_u64 (mp->features));
13017   vat_json_object_add_uint (node, "is_server", mp->is_server);
13018   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13019   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13020   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13021 }
13022
13023 static int
13024 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13025 {
13026   vl_api_sw_interface_vhost_user_dump_t *mp;
13027   vl_api_control_ping_t *mp_ping;
13028   int ret;
13029   print (vam->ofp,
13030          "Interface name            idx hdr_sz features server regions filename");
13031
13032   /* Get list of vhost-user interfaces */
13033   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13034   S (mp);
13035
13036   /* Use a control ping for synchronization */
13037   MPING (CONTROL_PING, mp_ping);
13038   S (mp_ping);
13039
13040   W (ret);
13041   return ret;
13042 }
13043
13044 static int
13045 api_show_version (vat_main_t * vam)
13046 {
13047   vl_api_show_version_t *mp;
13048   int ret;
13049
13050   M (SHOW_VERSION, mp);
13051
13052   S (mp);
13053   W (ret);
13054   return ret;
13055 }
13056
13057
13058 static int
13059 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13060 {
13061   unformat_input_t *line_input = vam->input;
13062   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13063   ip4_address_t local4, remote4;
13064   ip6_address_t local6, remote6;
13065   u8 is_add = 1;
13066   u8 ipv4_set = 0, ipv6_set = 0;
13067   u8 local_set = 0;
13068   u8 remote_set = 0;
13069   u8 grp_set = 0;
13070   u32 mcast_sw_if_index = ~0;
13071   u32 encap_vrf_id = 0;
13072   u32 decap_vrf_id = 0;
13073   u8 protocol = ~0;
13074   u32 vni;
13075   u8 vni_set = 0;
13076   int ret;
13077
13078   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13079   memset (&local4, 0, sizeof local4);
13080   memset (&remote4, 0, sizeof remote4);
13081   memset (&local6, 0, sizeof local6);
13082   memset (&remote6, 0, sizeof remote6);
13083
13084   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13085     {
13086       if (unformat (line_input, "del"))
13087         is_add = 0;
13088       else if (unformat (line_input, "local %U",
13089                          unformat_ip4_address, &local4))
13090         {
13091           local_set = 1;
13092           ipv4_set = 1;
13093         }
13094       else if (unformat (line_input, "remote %U",
13095                          unformat_ip4_address, &remote4))
13096         {
13097           remote_set = 1;
13098           ipv4_set = 1;
13099         }
13100       else if (unformat (line_input, "local %U",
13101                          unformat_ip6_address, &local6))
13102         {
13103           local_set = 1;
13104           ipv6_set = 1;
13105         }
13106       else if (unformat (line_input, "remote %U",
13107                          unformat_ip6_address, &remote6))
13108         {
13109           remote_set = 1;
13110           ipv6_set = 1;
13111         }
13112       else if (unformat (line_input, "group %U %U",
13113                          unformat_ip4_address, &remote4,
13114                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13115         {
13116           grp_set = remote_set = 1;
13117           ipv4_set = 1;
13118         }
13119       else if (unformat (line_input, "group %U",
13120                          unformat_ip4_address, &remote4))
13121         {
13122           grp_set = remote_set = 1;
13123           ipv4_set = 1;
13124         }
13125       else if (unformat (line_input, "group %U %U",
13126                          unformat_ip6_address, &remote6,
13127                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13128         {
13129           grp_set = remote_set = 1;
13130           ipv6_set = 1;
13131         }
13132       else if (unformat (line_input, "group %U",
13133                          unformat_ip6_address, &remote6))
13134         {
13135           grp_set = remote_set = 1;
13136           ipv6_set = 1;
13137         }
13138       else
13139         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13140         ;
13141       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13142         ;
13143       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13144         ;
13145       else if (unformat (line_input, "vni %d", &vni))
13146         vni_set = 1;
13147       else if (unformat (line_input, "next-ip4"))
13148         protocol = 1;
13149       else if (unformat (line_input, "next-ip6"))
13150         protocol = 2;
13151       else if (unformat (line_input, "next-ethernet"))
13152         protocol = 3;
13153       else if (unformat (line_input, "next-nsh"))
13154         protocol = 4;
13155       else
13156         {
13157           errmsg ("parse error '%U'", format_unformat_error, line_input);
13158           return -99;
13159         }
13160     }
13161
13162   if (local_set == 0)
13163     {
13164       errmsg ("tunnel local address not specified");
13165       return -99;
13166     }
13167   if (remote_set == 0)
13168     {
13169       errmsg ("tunnel remote address not specified");
13170       return -99;
13171     }
13172   if (grp_set && mcast_sw_if_index == ~0)
13173     {
13174       errmsg ("tunnel nonexistent multicast device");
13175       return -99;
13176     }
13177   if (ipv4_set && ipv6_set)
13178     {
13179       errmsg ("both IPv4 and IPv6 addresses specified");
13180       return -99;
13181     }
13182
13183   if (vni_set == 0)
13184     {
13185       errmsg ("vni not specified");
13186       return -99;
13187     }
13188
13189   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13190
13191
13192   if (ipv6_set)
13193     {
13194       clib_memcpy (&mp->local, &local6, sizeof (local6));
13195       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13196     }
13197   else
13198     {
13199       clib_memcpy (&mp->local, &local4, sizeof (local4));
13200       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13201     }
13202
13203   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13204   mp->encap_vrf_id = ntohl (encap_vrf_id);
13205   mp->decap_vrf_id = ntohl (decap_vrf_id);
13206   mp->protocol = protocol;
13207   mp->vni = ntohl (vni);
13208   mp->is_add = is_add;
13209   mp->is_ipv6 = ipv6_set;
13210
13211   S (mp);
13212   W (ret);
13213   return ret;
13214 }
13215
13216 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13217   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13218 {
13219   vat_main_t *vam = &vat_main;
13220   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13221   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13222
13223   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13224          ntohl (mp->sw_if_index),
13225          format_ip46_address, &local, IP46_TYPE_ANY,
13226          format_ip46_address, &remote, IP46_TYPE_ANY,
13227          ntohl (mp->vni), mp->protocol,
13228          ntohl (mp->mcast_sw_if_index),
13229          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13230 }
13231
13232
13233 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13234   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13235 {
13236   vat_main_t *vam = &vat_main;
13237   vat_json_node_t *node = NULL;
13238   struct in_addr ip4;
13239   struct in6_addr ip6;
13240
13241   if (VAT_JSON_ARRAY != vam->json_tree.type)
13242     {
13243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13244       vat_json_init_array (&vam->json_tree);
13245     }
13246   node = vat_json_array_add (&vam->json_tree);
13247
13248   vat_json_init_object (node);
13249   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13250   if (mp->is_ipv6)
13251     {
13252       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13253       vat_json_object_add_ip6 (node, "local", ip6);
13254       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13255       vat_json_object_add_ip6 (node, "remote", ip6);
13256     }
13257   else
13258     {
13259       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13260       vat_json_object_add_ip4 (node, "local", ip4);
13261       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13262       vat_json_object_add_ip4 (node, "remote", ip4);
13263     }
13264   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13265   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13266   vat_json_object_add_uint (node, "mcast_sw_if_index",
13267                             ntohl (mp->mcast_sw_if_index));
13268   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13269   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13270   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13271 }
13272
13273 static int
13274 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13275 {
13276   unformat_input_t *i = vam->input;
13277   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13278   vl_api_control_ping_t *mp_ping;
13279   u32 sw_if_index;
13280   u8 sw_if_index_set = 0;
13281   int ret;
13282
13283   /* Parse args required to build the message */
13284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (i, "sw_if_index %d", &sw_if_index))
13287         sw_if_index_set = 1;
13288       else
13289         break;
13290     }
13291
13292   if (sw_if_index_set == 0)
13293     {
13294       sw_if_index = ~0;
13295     }
13296
13297   if (!vam->json_output)
13298     {
13299       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13300              "sw_if_index", "local", "remote", "vni",
13301              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13302     }
13303
13304   /* Get list of vxlan-tunnel interfaces */
13305   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13306
13307   mp->sw_if_index = htonl (sw_if_index);
13308
13309   S (mp);
13310
13311   /* Use a control ping for synchronization */
13312   MPING (CONTROL_PING, mp_ping);
13313   S (mp_ping);
13314
13315   W (ret);
13316   return ret;
13317 }
13318
13319 static void vl_api_l2_fib_table_details_t_handler
13320   (vl_api_l2_fib_table_details_t * mp)
13321 {
13322   vat_main_t *vam = &vat_main;
13323
13324   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13325          "       %d       %d     %d",
13326          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13327          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13328          mp->bvi_mac);
13329 }
13330
13331 static void vl_api_l2_fib_table_details_t_handler_json
13332   (vl_api_l2_fib_table_details_t * mp)
13333 {
13334   vat_main_t *vam = &vat_main;
13335   vat_json_node_t *node = NULL;
13336
13337   if (VAT_JSON_ARRAY != vam->json_tree.type)
13338     {
13339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13340       vat_json_init_array (&vam->json_tree);
13341     }
13342   node = vat_json_array_add (&vam->json_tree);
13343
13344   vat_json_init_object (node);
13345   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13346   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13347   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13348   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13349   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13350   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13351 }
13352
13353 static int
13354 api_l2_fib_table_dump (vat_main_t * vam)
13355 {
13356   unformat_input_t *i = vam->input;
13357   vl_api_l2_fib_table_dump_t *mp;
13358   vl_api_control_ping_t *mp_ping;
13359   u32 bd_id;
13360   u8 bd_id_set = 0;
13361   int ret;
13362
13363   /* Parse args required to build the message */
13364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13365     {
13366       if (unformat (i, "bd_id %d", &bd_id))
13367         bd_id_set = 1;
13368       else
13369         break;
13370     }
13371
13372   if (bd_id_set == 0)
13373     {
13374       errmsg ("missing bridge domain");
13375       return -99;
13376     }
13377
13378   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13379
13380   /* Get list of l2 fib entries */
13381   M (L2_FIB_TABLE_DUMP, mp);
13382
13383   mp->bd_id = ntohl (bd_id);
13384   S (mp);
13385
13386   /* Use a control ping for synchronization */
13387   MPING (CONTROL_PING, mp_ping);
13388   S (mp_ping);
13389
13390   W (ret);
13391   return ret;
13392 }
13393
13394
13395 static int
13396 api_interface_name_renumber (vat_main_t * vam)
13397 {
13398   unformat_input_t *line_input = vam->input;
13399   vl_api_interface_name_renumber_t *mp;
13400   u32 sw_if_index = ~0;
13401   u32 new_show_dev_instance = ~0;
13402   int ret;
13403
13404   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13405     {
13406       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13407                     &sw_if_index))
13408         ;
13409       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13410         ;
13411       else if (unformat (line_input, "new_show_dev_instance %d",
13412                          &new_show_dev_instance))
13413         ;
13414       else
13415         break;
13416     }
13417
13418   if (sw_if_index == ~0)
13419     {
13420       errmsg ("missing interface name or sw_if_index");
13421       return -99;
13422     }
13423
13424   if (new_show_dev_instance == ~0)
13425     {
13426       errmsg ("missing new_show_dev_instance");
13427       return -99;
13428     }
13429
13430   M (INTERFACE_NAME_RENUMBER, mp);
13431
13432   mp->sw_if_index = ntohl (sw_if_index);
13433   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13434
13435   S (mp);
13436   W (ret);
13437   return ret;
13438 }
13439
13440 static int
13441 api_want_ip4_arp_events (vat_main_t * vam)
13442 {
13443   unformat_input_t *line_input = vam->input;
13444   vl_api_want_ip4_arp_events_t *mp;
13445   ip4_address_t address;
13446   int address_set = 0;
13447   u32 enable_disable = 1;
13448   int ret;
13449
13450   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13451     {
13452       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13453         address_set = 1;
13454       else if (unformat (line_input, "del"))
13455         enable_disable = 0;
13456       else
13457         break;
13458     }
13459
13460   if (address_set == 0)
13461     {
13462       errmsg ("missing addresses");
13463       return -99;
13464     }
13465
13466   M (WANT_IP4_ARP_EVENTS, mp);
13467   mp->enable_disable = enable_disable;
13468   mp->pid = htonl (getpid ());
13469   mp->address = address.as_u32;
13470
13471   S (mp);
13472   W (ret);
13473   return ret;
13474 }
13475
13476 static int
13477 api_want_ip6_nd_events (vat_main_t * vam)
13478 {
13479   unformat_input_t *line_input = vam->input;
13480   vl_api_want_ip6_nd_events_t *mp;
13481   ip6_address_t address;
13482   int address_set = 0;
13483   u32 enable_disable = 1;
13484   int ret;
13485
13486   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13489         address_set = 1;
13490       else if (unformat (line_input, "del"))
13491         enable_disable = 0;
13492       else
13493         break;
13494     }
13495
13496   if (address_set == 0)
13497     {
13498       errmsg ("missing addresses");
13499       return -99;
13500     }
13501
13502   M (WANT_IP6_ND_EVENTS, mp);
13503   mp->enable_disable = enable_disable;
13504   mp->pid = htonl (getpid ());
13505   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13506
13507   S (mp);
13508   W (ret);
13509   return ret;
13510 }
13511
13512 static int
13513 api_want_l2_macs_events (vat_main_t * vam)
13514 {
13515   unformat_input_t *line_input = vam->input;
13516   vl_api_want_l2_macs_events_t *mp;
13517   u8 enable_disable = 1;
13518   u32 scan_delay = 0;
13519   u32 max_macs_in_event = 0;
13520   u32 learn_limit = 0;
13521   int ret;
13522
13523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13524     {
13525       if (unformat (line_input, "learn-limit %d", &learn_limit))
13526         ;
13527       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13528         ;
13529       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13530         ;
13531       else if (unformat (line_input, "disable"))
13532         enable_disable = 0;
13533       else
13534         break;
13535     }
13536
13537   M (WANT_L2_MACS_EVENTS, mp);
13538   mp->enable_disable = enable_disable;
13539   mp->pid = htonl (getpid ());
13540   mp->learn_limit = htonl (learn_limit);
13541   mp->scan_delay = (u8) scan_delay;
13542   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13543   S (mp);
13544   W (ret);
13545   return ret;
13546 }
13547
13548 static int
13549 api_input_acl_set_interface (vat_main_t * vam)
13550 {
13551   unformat_input_t *i = vam->input;
13552   vl_api_input_acl_set_interface_t *mp;
13553   u32 sw_if_index;
13554   int sw_if_index_set;
13555   u32 ip4_table_index = ~0;
13556   u32 ip6_table_index = ~0;
13557   u32 l2_table_index = ~0;
13558   u8 is_add = 1;
13559   int ret;
13560
13561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13562     {
13563       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13564         sw_if_index_set = 1;
13565       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13566         sw_if_index_set = 1;
13567       else if (unformat (i, "del"))
13568         is_add = 0;
13569       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13570         ;
13571       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13572         ;
13573       else if (unformat (i, "l2-table %d", &l2_table_index))
13574         ;
13575       else
13576         {
13577           clib_warning ("parse error '%U'", format_unformat_error, i);
13578           return -99;
13579         }
13580     }
13581
13582   if (sw_if_index_set == 0)
13583     {
13584       errmsg ("missing interface name or sw_if_index");
13585       return -99;
13586     }
13587
13588   M (INPUT_ACL_SET_INTERFACE, mp);
13589
13590   mp->sw_if_index = ntohl (sw_if_index);
13591   mp->ip4_table_index = ntohl (ip4_table_index);
13592   mp->ip6_table_index = ntohl (ip6_table_index);
13593   mp->l2_table_index = ntohl (l2_table_index);
13594   mp->is_add = is_add;
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_ip_address_dump (vat_main_t * vam)
13603 {
13604   unformat_input_t *i = vam->input;
13605   vl_api_ip_address_dump_t *mp;
13606   vl_api_control_ping_t *mp_ping;
13607   u32 sw_if_index = ~0;
13608   u8 sw_if_index_set = 0;
13609   u8 ipv4_set = 0;
13610   u8 ipv6_set = 0;
13611   int ret;
13612
13613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (i, "sw_if_index %d", &sw_if_index))
13616         sw_if_index_set = 1;
13617       else
13618         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13619         sw_if_index_set = 1;
13620       else if (unformat (i, "ipv4"))
13621         ipv4_set = 1;
13622       else if (unformat (i, "ipv6"))
13623         ipv6_set = 1;
13624       else
13625         break;
13626     }
13627
13628   if (ipv4_set && ipv6_set)
13629     {
13630       errmsg ("ipv4 and ipv6 flags cannot be both set");
13631       return -99;
13632     }
13633
13634   if ((!ipv4_set) && (!ipv6_set))
13635     {
13636       errmsg ("no ipv4 nor ipv6 flag set");
13637       return -99;
13638     }
13639
13640   if (sw_if_index_set == 0)
13641     {
13642       errmsg ("missing interface name or sw_if_index");
13643       return -99;
13644     }
13645
13646   vam->current_sw_if_index = sw_if_index;
13647   vam->is_ipv6 = ipv6_set;
13648
13649   M (IP_ADDRESS_DUMP, mp);
13650   mp->sw_if_index = ntohl (sw_if_index);
13651   mp->is_ipv6 = ipv6_set;
13652   S (mp);
13653
13654   /* Use a control ping for synchronization */
13655   MPING (CONTROL_PING, mp_ping);
13656   S (mp_ping);
13657
13658   W (ret);
13659   return ret;
13660 }
13661
13662 static int
13663 api_ip_dump (vat_main_t * vam)
13664 {
13665   vl_api_ip_dump_t *mp;
13666   vl_api_control_ping_t *mp_ping;
13667   unformat_input_t *in = vam->input;
13668   int ipv4_set = 0;
13669   int ipv6_set = 0;
13670   int is_ipv6;
13671   int i;
13672   int ret;
13673
13674   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13675     {
13676       if (unformat (in, "ipv4"))
13677         ipv4_set = 1;
13678       else if (unformat (in, "ipv6"))
13679         ipv6_set = 1;
13680       else
13681         break;
13682     }
13683
13684   if (ipv4_set && ipv6_set)
13685     {
13686       errmsg ("ipv4 and ipv6 flags cannot be both set");
13687       return -99;
13688     }
13689
13690   if ((!ipv4_set) && (!ipv6_set))
13691     {
13692       errmsg ("no ipv4 nor ipv6 flag set");
13693       return -99;
13694     }
13695
13696   is_ipv6 = ipv6_set;
13697   vam->is_ipv6 = is_ipv6;
13698
13699   /* free old data */
13700   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13701     {
13702       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13703     }
13704   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13705
13706   M (IP_DUMP, mp);
13707   mp->is_ipv6 = ipv6_set;
13708   S (mp);
13709
13710   /* Use a control ping for synchronization */
13711   MPING (CONTROL_PING, mp_ping);
13712   S (mp_ping);
13713
13714   W (ret);
13715   return ret;
13716 }
13717
13718 static int
13719 api_ipsec_spd_add_del (vat_main_t * vam)
13720 {
13721   unformat_input_t *i = vam->input;
13722   vl_api_ipsec_spd_add_del_t *mp;
13723   u32 spd_id = ~0;
13724   u8 is_add = 1;
13725   int ret;
13726
13727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (i, "spd_id %d", &spd_id))
13730         ;
13731       else if (unformat (i, "del"))
13732         is_add = 0;
13733       else
13734         {
13735           clib_warning ("parse error '%U'", format_unformat_error, i);
13736           return -99;
13737         }
13738     }
13739   if (spd_id == ~0)
13740     {
13741       errmsg ("spd_id must be set");
13742       return -99;
13743     }
13744
13745   M (IPSEC_SPD_ADD_DEL, mp);
13746
13747   mp->spd_id = ntohl (spd_id);
13748   mp->is_add = is_add;
13749
13750   S (mp);
13751   W (ret);
13752   return ret;
13753 }
13754
13755 static int
13756 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13757 {
13758   unformat_input_t *i = vam->input;
13759   vl_api_ipsec_interface_add_del_spd_t *mp;
13760   u32 sw_if_index;
13761   u8 sw_if_index_set = 0;
13762   u32 spd_id = (u32) ~ 0;
13763   u8 is_add = 1;
13764   int ret;
13765
13766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13767     {
13768       if (unformat (i, "del"))
13769         is_add = 0;
13770       else if (unformat (i, "spd_id %d", &spd_id))
13771         ;
13772       else
13773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13774         sw_if_index_set = 1;
13775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13776         sw_if_index_set = 1;
13777       else
13778         {
13779           clib_warning ("parse error '%U'", format_unformat_error, i);
13780           return -99;
13781         }
13782
13783     }
13784
13785   if (spd_id == (u32) ~ 0)
13786     {
13787       errmsg ("spd_id must be set");
13788       return -99;
13789     }
13790
13791   if (sw_if_index_set == 0)
13792     {
13793       errmsg ("missing interface name or sw_if_index");
13794       return -99;
13795     }
13796
13797   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13798
13799   mp->spd_id = ntohl (spd_id);
13800   mp->sw_if_index = ntohl (sw_if_index);
13801   mp->is_add = is_add;
13802
13803   S (mp);
13804   W (ret);
13805   return ret;
13806 }
13807
13808 static int
13809 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13810 {
13811   unformat_input_t *i = vam->input;
13812   vl_api_ipsec_spd_add_del_entry_t *mp;
13813   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13814   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13815   i32 priority = 0;
13816   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13817   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13818   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13819   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13820   int ret;
13821
13822   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13823   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13824   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13825   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13826   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13827   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13828
13829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13830     {
13831       if (unformat (i, "del"))
13832         is_add = 0;
13833       if (unformat (i, "outbound"))
13834         is_outbound = 1;
13835       if (unformat (i, "inbound"))
13836         is_outbound = 0;
13837       else if (unformat (i, "spd_id %d", &spd_id))
13838         ;
13839       else if (unformat (i, "sa_id %d", &sa_id))
13840         ;
13841       else if (unformat (i, "priority %d", &priority))
13842         ;
13843       else if (unformat (i, "protocol %d", &protocol))
13844         ;
13845       else if (unformat (i, "lport_start %d", &lport_start))
13846         ;
13847       else if (unformat (i, "lport_stop %d", &lport_stop))
13848         ;
13849       else if (unformat (i, "rport_start %d", &rport_start))
13850         ;
13851       else if (unformat (i, "rport_stop %d", &rport_stop))
13852         ;
13853       else
13854         if (unformat
13855             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13856         {
13857           is_ipv6 = 0;
13858           is_ip_any = 0;
13859         }
13860       else
13861         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13862         {
13863           is_ipv6 = 0;
13864           is_ip_any = 0;
13865         }
13866       else
13867         if (unformat
13868             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13869         {
13870           is_ipv6 = 0;
13871           is_ip_any = 0;
13872         }
13873       else
13874         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13875         {
13876           is_ipv6 = 0;
13877           is_ip_any = 0;
13878         }
13879       else
13880         if (unformat
13881             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13882         {
13883           is_ipv6 = 1;
13884           is_ip_any = 0;
13885         }
13886       else
13887         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13888         {
13889           is_ipv6 = 1;
13890           is_ip_any = 0;
13891         }
13892       else
13893         if (unformat
13894             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13895         {
13896           is_ipv6 = 1;
13897           is_ip_any = 0;
13898         }
13899       else
13900         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13901         {
13902           is_ipv6 = 1;
13903           is_ip_any = 0;
13904         }
13905       else
13906         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13907         {
13908           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13909             {
13910               clib_warning ("unsupported action: 'resolve'");
13911               return -99;
13912             }
13913         }
13914       else
13915         {
13916           clib_warning ("parse error '%U'", format_unformat_error, i);
13917           return -99;
13918         }
13919
13920     }
13921
13922   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13923
13924   mp->spd_id = ntohl (spd_id);
13925   mp->priority = ntohl (priority);
13926   mp->is_outbound = is_outbound;
13927
13928   mp->is_ipv6 = is_ipv6;
13929   if (is_ipv6 || is_ip_any)
13930     {
13931       clib_memcpy (mp->remote_address_start, &raddr6_start,
13932                    sizeof (ip6_address_t));
13933       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13934                    sizeof (ip6_address_t));
13935       clib_memcpy (mp->local_address_start, &laddr6_start,
13936                    sizeof (ip6_address_t));
13937       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13938                    sizeof (ip6_address_t));
13939     }
13940   else
13941     {
13942       clib_memcpy (mp->remote_address_start, &raddr4_start,
13943                    sizeof (ip4_address_t));
13944       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13945                    sizeof (ip4_address_t));
13946       clib_memcpy (mp->local_address_start, &laddr4_start,
13947                    sizeof (ip4_address_t));
13948       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13949                    sizeof (ip4_address_t));
13950     }
13951   mp->protocol = (u8) protocol;
13952   mp->local_port_start = ntohs ((u16) lport_start);
13953   mp->local_port_stop = ntohs ((u16) lport_stop);
13954   mp->remote_port_start = ntohs ((u16) rport_start);
13955   mp->remote_port_stop = ntohs ((u16) rport_stop);
13956   mp->policy = (u8) policy;
13957   mp->sa_id = ntohl (sa_id);
13958   mp->is_add = is_add;
13959   mp->is_ip_any = is_ip_any;
13960   S (mp);
13961   W (ret);
13962   return ret;
13963 }
13964
13965 static int
13966 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13967 {
13968   unformat_input_t *i = vam->input;
13969   vl_api_ipsec_sad_add_del_entry_t *mp;
13970   u32 sad_id = 0, spi = 0;
13971   u8 *ck = 0, *ik = 0;
13972   u8 is_add = 1;
13973
13974   u8 protocol = IPSEC_PROTOCOL_AH;
13975   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13976   u32 crypto_alg = 0, integ_alg = 0;
13977   ip4_address_t tun_src4;
13978   ip4_address_t tun_dst4;
13979   ip6_address_t tun_src6;
13980   ip6_address_t tun_dst6;
13981   int ret;
13982
13983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13984     {
13985       if (unformat (i, "del"))
13986         is_add = 0;
13987       else if (unformat (i, "sad_id %d", &sad_id))
13988         ;
13989       else if (unformat (i, "spi %d", &spi))
13990         ;
13991       else if (unformat (i, "esp"))
13992         protocol = IPSEC_PROTOCOL_ESP;
13993       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13994         {
13995           is_tunnel = 1;
13996           is_tunnel_ipv6 = 0;
13997         }
13998       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13999         {
14000           is_tunnel = 1;
14001           is_tunnel_ipv6 = 0;
14002         }
14003       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14004         {
14005           is_tunnel = 1;
14006           is_tunnel_ipv6 = 1;
14007         }
14008       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14009         {
14010           is_tunnel = 1;
14011           is_tunnel_ipv6 = 1;
14012         }
14013       else
14014         if (unformat
14015             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14016         {
14017           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14018               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14019             {
14020               clib_warning ("unsupported crypto-alg: '%U'",
14021                             format_ipsec_crypto_alg, crypto_alg);
14022               return -99;
14023             }
14024         }
14025       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14026         ;
14027       else
14028         if (unformat
14029             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14030         {
14031           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14032               integ_alg >= IPSEC_INTEG_N_ALG)
14033             {
14034               clib_warning ("unsupported integ-alg: '%U'",
14035                             format_ipsec_integ_alg, integ_alg);
14036               return -99;
14037             }
14038         }
14039       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14040         ;
14041       else
14042         {
14043           clib_warning ("parse error '%U'", format_unformat_error, i);
14044           return -99;
14045         }
14046
14047     }
14048
14049   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14050
14051   mp->sad_id = ntohl (sad_id);
14052   mp->is_add = is_add;
14053   mp->protocol = protocol;
14054   mp->spi = ntohl (spi);
14055   mp->is_tunnel = is_tunnel;
14056   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14057   mp->crypto_algorithm = crypto_alg;
14058   mp->integrity_algorithm = integ_alg;
14059   mp->crypto_key_length = vec_len (ck);
14060   mp->integrity_key_length = vec_len (ik);
14061
14062   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14063     mp->crypto_key_length = sizeof (mp->crypto_key);
14064
14065   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14066     mp->integrity_key_length = sizeof (mp->integrity_key);
14067
14068   if (ck)
14069     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14070   if (ik)
14071     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14072
14073   if (is_tunnel)
14074     {
14075       if (is_tunnel_ipv6)
14076         {
14077           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14078                        sizeof (ip6_address_t));
14079           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14080                        sizeof (ip6_address_t));
14081         }
14082       else
14083         {
14084           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14085                        sizeof (ip4_address_t));
14086           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14087                        sizeof (ip4_address_t));
14088         }
14089     }
14090
14091   S (mp);
14092   W (ret);
14093   return ret;
14094 }
14095
14096 static int
14097 api_ipsec_sa_set_key (vat_main_t * vam)
14098 {
14099   unformat_input_t *i = vam->input;
14100   vl_api_ipsec_sa_set_key_t *mp;
14101   u32 sa_id;
14102   u8 *ck = 0, *ik = 0;
14103   int ret;
14104
14105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (i, "sa_id %d", &sa_id))
14108         ;
14109       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14110         ;
14111       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14112         ;
14113       else
14114         {
14115           clib_warning ("parse error '%U'", format_unformat_error, i);
14116           return -99;
14117         }
14118     }
14119
14120   M (IPSEC_SA_SET_KEY, mp);
14121
14122   mp->sa_id = ntohl (sa_id);
14123   mp->crypto_key_length = vec_len (ck);
14124   mp->integrity_key_length = vec_len (ik);
14125
14126   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14127     mp->crypto_key_length = sizeof (mp->crypto_key);
14128
14129   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14130     mp->integrity_key_length = sizeof (mp->integrity_key);
14131
14132   if (ck)
14133     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14134   if (ik)
14135     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14136
14137   S (mp);
14138   W (ret);
14139   return ret;
14140 }
14141
14142 static int
14143 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14144 {
14145   unformat_input_t *i = vam->input;
14146   vl_api_ipsec_tunnel_if_add_del_t *mp;
14147   u32 local_spi = 0, remote_spi = 0;
14148   u32 crypto_alg = 0, integ_alg = 0;
14149   u8 *lck = NULL, *rck = NULL;
14150   u8 *lik = NULL, *rik = NULL;
14151   ip4_address_t local_ip = { {0} };
14152   ip4_address_t remote_ip = { {0} };
14153   u8 is_add = 1;
14154   u8 esn = 0;
14155   u8 anti_replay = 0;
14156   int ret;
14157
14158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (i, "del"))
14161         is_add = 0;
14162       else if (unformat (i, "esn"))
14163         esn = 1;
14164       else if (unformat (i, "anti_replay"))
14165         anti_replay = 1;
14166       else if (unformat (i, "local_spi %d", &local_spi))
14167         ;
14168       else if (unformat (i, "remote_spi %d", &remote_spi))
14169         ;
14170       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14171         ;
14172       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14173         ;
14174       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14175         ;
14176       else
14177         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14178         ;
14179       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14180         ;
14181       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14182         ;
14183       else
14184         if (unformat
14185             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14186         {
14187           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14188               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14189             {
14190               errmsg ("unsupported crypto-alg: '%U'\n",
14191                       format_ipsec_crypto_alg, crypto_alg);
14192               return -99;
14193             }
14194         }
14195       else
14196         if (unformat
14197             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14198         {
14199           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14200               integ_alg >= IPSEC_INTEG_N_ALG)
14201             {
14202               errmsg ("unsupported integ-alg: '%U'\n",
14203                       format_ipsec_integ_alg, integ_alg);
14204               return -99;
14205             }
14206         }
14207       else
14208         {
14209           errmsg ("parse error '%U'\n", format_unformat_error, i);
14210           return -99;
14211         }
14212     }
14213
14214   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14215
14216   mp->is_add = is_add;
14217   mp->esn = esn;
14218   mp->anti_replay = anti_replay;
14219
14220   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14221   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14222
14223   mp->local_spi = htonl (local_spi);
14224   mp->remote_spi = htonl (remote_spi);
14225   mp->crypto_alg = (u8) crypto_alg;
14226
14227   mp->local_crypto_key_len = 0;
14228   if (lck)
14229     {
14230       mp->local_crypto_key_len = vec_len (lck);
14231       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14232         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14233       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14234     }
14235
14236   mp->remote_crypto_key_len = 0;
14237   if (rck)
14238     {
14239       mp->remote_crypto_key_len = vec_len (rck);
14240       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14241         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14242       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14243     }
14244
14245   mp->integ_alg = (u8) integ_alg;
14246
14247   mp->local_integ_key_len = 0;
14248   if (lik)
14249     {
14250       mp->local_integ_key_len = vec_len (lik);
14251       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14252         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14253       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14254     }
14255
14256   mp->remote_integ_key_len = 0;
14257   if (rik)
14258     {
14259       mp->remote_integ_key_len = vec_len (rik);
14260       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14261         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14262       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14263     }
14264
14265   S (mp);
14266   W (ret);
14267   return ret;
14268 }
14269
14270 static void
14271 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14272 {
14273   vat_main_t *vam = &vat_main;
14274
14275   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14276          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14277          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14278          "tunnel_src_addr %U tunnel_dst_addr %U "
14279          "salt %u seq_outbound %lu last_seq_inbound %lu "
14280          "replay_window %lu total_data_size %lu\n",
14281          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14282          mp->protocol,
14283          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14284          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14285          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14286          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14287          mp->tunnel_src_addr,
14288          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14289          mp->tunnel_dst_addr,
14290          ntohl (mp->salt),
14291          clib_net_to_host_u64 (mp->seq_outbound),
14292          clib_net_to_host_u64 (mp->last_seq_inbound),
14293          clib_net_to_host_u64 (mp->replay_window),
14294          clib_net_to_host_u64 (mp->total_data_size));
14295 }
14296
14297 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14298 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14299
14300 static void vl_api_ipsec_sa_details_t_handler_json
14301   (vl_api_ipsec_sa_details_t * mp)
14302 {
14303   vat_main_t *vam = &vat_main;
14304   vat_json_node_t *node = NULL;
14305   struct in_addr src_ip4, dst_ip4;
14306   struct in6_addr src_ip6, dst_ip6;
14307
14308   if (VAT_JSON_ARRAY != vam->json_tree.type)
14309     {
14310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14311       vat_json_init_array (&vam->json_tree);
14312     }
14313   node = vat_json_array_add (&vam->json_tree);
14314
14315   vat_json_init_object (node);
14316   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14317   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14318   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14319   vat_json_object_add_uint (node, "proto", mp->protocol);
14320   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14321   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14322   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14323   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14324   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14325   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14326   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14327                              mp->crypto_key_len);
14328   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14329                              mp->integ_key_len);
14330   if (mp->is_tunnel_ip6)
14331     {
14332       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14333       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14334       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14335       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14336     }
14337   else
14338     {
14339       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14340       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14341       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14342       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14343     }
14344   vat_json_object_add_uint (node, "replay_window",
14345                             clib_net_to_host_u64 (mp->replay_window));
14346   vat_json_object_add_uint (node, "total_data_size",
14347                             clib_net_to_host_u64 (mp->total_data_size));
14348
14349 }
14350
14351 static int
14352 api_ipsec_sa_dump (vat_main_t * vam)
14353 {
14354   unformat_input_t *i = vam->input;
14355   vl_api_ipsec_sa_dump_t *mp;
14356   vl_api_control_ping_t *mp_ping;
14357   u32 sa_id = ~0;
14358   int ret;
14359
14360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14361     {
14362       if (unformat (i, "sa_id %d", &sa_id))
14363         ;
14364       else
14365         {
14366           clib_warning ("parse error '%U'", format_unformat_error, i);
14367           return -99;
14368         }
14369     }
14370
14371   M (IPSEC_SA_DUMP, mp);
14372
14373   mp->sa_id = ntohl (sa_id);
14374
14375   S (mp);
14376
14377   /* Use a control ping for synchronization */
14378   M (CONTROL_PING, mp_ping);
14379   S (mp_ping);
14380
14381   W (ret);
14382   return ret;
14383 }
14384
14385 static int
14386 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14387 {
14388   unformat_input_t *i = vam->input;
14389   vl_api_ipsec_tunnel_if_set_key_t *mp;
14390   u32 sw_if_index = ~0;
14391   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14392   u8 *key = 0;
14393   u32 alg = ~0;
14394   int ret;
14395
14396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14397     {
14398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14399         ;
14400       else
14401         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14402         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14403       else
14404         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14405         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14406       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14407         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14408       else
14409         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14410         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14411       else if (unformat (i, "%U", unformat_hex_string, &key))
14412         ;
14413       else
14414         {
14415           clib_warning ("parse error '%U'", format_unformat_error, i);
14416           return -99;
14417         }
14418     }
14419
14420   if (sw_if_index == ~0)
14421     {
14422       errmsg ("interface must be specified");
14423       return -99;
14424     }
14425
14426   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14427     {
14428       errmsg ("key type must be specified");
14429       return -99;
14430     }
14431
14432   if (alg == ~0)
14433     {
14434       errmsg ("algorithm must be specified");
14435       return -99;
14436     }
14437
14438   if (vec_len (key) == 0)
14439     {
14440       errmsg ("key must be specified");
14441       return -99;
14442     }
14443
14444   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14445
14446   mp->sw_if_index = htonl (sw_if_index);
14447   mp->alg = alg;
14448   mp->key_type = key_type;
14449   mp->key_len = vec_len (key);
14450   clib_memcpy (mp->key, key, vec_len (key));
14451
14452   S (mp);
14453   W (ret);
14454
14455   return ret;
14456 }
14457
14458 static int
14459 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14460 {
14461   unformat_input_t *i = vam->input;
14462   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14463   u32 sw_if_index = ~0;
14464   u32 sa_id = ~0;
14465   u8 is_outbound = (u8) ~ 0;
14466   int ret;
14467
14468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14469     {
14470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14471         ;
14472       else if (unformat (i, "sa_id %d", &sa_id))
14473         ;
14474       else if (unformat (i, "outbound"))
14475         is_outbound = 1;
14476       else if (unformat (i, "inbound"))
14477         is_outbound = 0;
14478       else
14479         {
14480           clib_warning ("parse error '%U'", format_unformat_error, i);
14481           return -99;
14482         }
14483     }
14484
14485   if (sw_if_index == ~0)
14486     {
14487       errmsg ("interface must be specified");
14488       return -99;
14489     }
14490
14491   if (sa_id == ~0)
14492     {
14493       errmsg ("SA ID must be specified");
14494       return -99;
14495     }
14496
14497   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14498
14499   mp->sw_if_index = htonl (sw_if_index);
14500   mp->sa_id = htonl (sa_id);
14501   mp->is_outbound = is_outbound;
14502
14503   S (mp);
14504   W (ret);
14505
14506   return ret;
14507 }
14508
14509 static int
14510 api_ikev2_profile_add_del (vat_main_t * vam)
14511 {
14512   unformat_input_t *i = vam->input;
14513   vl_api_ikev2_profile_add_del_t *mp;
14514   u8 is_add = 1;
14515   u8 *name = 0;
14516   int ret;
14517
14518   const char *valid_chars = "a-zA-Z0-9_";
14519
14520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (i, "del"))
14523         is_add = 0;
14524       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14525         vec_add1 (name, 0);
14526       else
14527         {
14528           errmsg ("parse error '%U'", format_unformat_error, i);
14529           return -99;
14530         }
14531     }
14532
14533   if (!vec_len (name))
14534     {
14535       errmsg ("profile name must be specified");
14536       return -99;
14537     }
14538
14539   if (vec_len (name) > 64)
14540     {
14541       errmsg ("profile name too long");
14542       return -99;
14543     }
14544
14545   M (IKEV2_PROFILE_ADD_DEL, mp);
14546
14547   clib_memcpy (mp->name, name, vec_len (name));
14548   mp->is_add = is_add;
14549   vec_free (name);
14550
14551   S (mp);
14552   W (ret);
14553   return ret;
14554 }
14555
14556 static int
14557 api_ikev2_profile_set_auth (vat_main_t * vam)
14558 {
14559   unformat_input_t *i = vam->input;
14560   vl_api_ikev2_profile_set_auth_t *mp;
14561   u8 *name = 0;
14562   u8 *data = 0;
14563   u32 auth_method = 0;
14564   u8 is_hex = 0;
14565   int ret;
14566
14567   const char *valid_chars = "a-zA-Z0-9_";
14568
14569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14570     {
14571       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14572         vec_add1 (name, 0);
14573       else if (unformat (i, "auth_method %U",
14574                          unformat_ikev2_auth_method, &auth_method))
14575         ;
14576       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14577         is_hex = 1;
14578       else if (unformat (i, "auth_data %v", &data))
14579         ;
14580       else
14581         {
14582           errmsg ("parse error '%U'", format_unformat_error, i);
14583           return -99;
14584         }
14585     }
14586
14587   if (!vec_len (name))
14588     {
14589       errmsg ("profile name must be specified");
14590       return -99;
14591     }
14592
14593   if (vec_len (name) > 64)
14594     {
14595       errmsg ("profile name too long");
14596       return -99;
14597     }
14598
14599   if (!vec_len (data))
14600     {
14601       errmsg ("auth_data must be specified");
14602       return -99;
14603     }
14604
14605   if (!auth_method)
14606     {
14607       errmsg ("auth_method must be specified");
14608       return -99;
14609     }
14610
14611   M (IKEV2_PROFILE_SET_AUTH, mp);
14612
14613   mp->is_hex = is_hex;
14614   mp->auth_method = (u8) auth_method;
14615   mp->data_len = vec_len (data);
14616   clib_memcpy (mp->name, name, vec_len (name));
14617   clib_memcpy (mp->data, data, vec_len (data));
14618   vec_free (name);
14619   vec_free (data);
14620
14621   S (mp);
14622   W (ret);
14623   return ret;
14624 }
14625
14626 static int
14627 api_ikev2_profile_set_id (vat_main_t * vam)
14628 {
14629   unformat_input_t *i = vam->input;
14630   vl_api_ikev2_profile_set_id_t *mp;
14631   u8 *name = 0;
14632   u8 *data = 0;
14633   u8 is_local = 0;
14634   u32 id_type = 0;
14635   ip4_address_t ip4;
14636   int ret;
14637
14638   const char *valid_chars = "a-zA-Z0-9_";
14639
14640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14641     {
14642       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14643         vec_add1 (name, 0);
14644       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14645         ;
14646       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14647         {
14648           data = vec_new (u8, 4);
14649           clib_memcpy (data, ip4.as_u8, 4);
14650         }
14651       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14652         ;
14653       else if (unformat (i, "id_data %v", &data))
14654         ;
14655       else if (unformat (i, "local"))
14656         is_local = 1;
14657       else if (unformat (i, "remote"))
14658         is_local = 0;
14659       else
14660         {
14661           errmsg ("parse error '%U'", format_unformat_error, i);
14662           return -99;
14663         }
14664     }
14665
14666   if (!vec_len (name))
14667     {
14668       errmsg ("profile name must be specified");
14669       return -99;
14670     }
14671
14672   if (vec_len (name) > 64)
14673     {
14674       errmsg ("profile name too long");
14675       return -99;
14676     }
14677
14678   if (!vec_len (data))
14679     {
14680       errmsg ("id_data must be specified");
14681       return -99;
14682     }
14683
14684   if (!id_type)
14685     {
14686       errmsg ("id_type must be specified");
14687       return -99;
14688     }
14689
14690   M (IKEV2_PROFILE_SET_ID, mp);
14691
14692   mp->is_local = is_local;
14693   mp->id_type = (u8) id_type;
14694   mp->data_len = vec_len (data);
14695   clib_memcpy (mp->name, name, vec_len (name));
14696   clib_memcpy (mp->data, data, vec_len (data));
14697   vec_free (name);
14698   vec_free (data);
14699
14700   S (mp);
14701   W (ret);
14702   return ret;
14703 }
14704
14705 static int
14706 api_ikev2_profile_set_ts (vat_main_t * vam)
14707 {
14708   unformat_input_t *i = vam->input;
14709   vl_api_ikev2_profile_set_ts_t *mp;
14710   u8 *name = 0;
14711   u8 is_local = 0;
14712   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14713   ip4_address_t start_addr, end_addr;
14714
14715   const char *valid_chars = "a-zA-Z0-9_";
14716   int ret;
14717
14718   start_addr.as_u32 = 0;
14719   end_addr.as_u32 = (u32) ~ 0;
14720
14721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14724         vec_add1 (name, 0);
14725       else if (unformat (i, "protocol %d", &proto))
14726         ;
14727       else if (unformat (i, "start_port %d", &start_port))
14728         ;
14729       else if (unformat (i, "end_port %d", &end_port))
14730         ;
14731       else
14732         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14733         ;
14734       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14735         ;
14736       else if (unformat (i, "local"))
14737         is_local = 1;
14738       else if (unformat (i, "remote"))
14739         is_local = 0;
14740       else
14741         {
14742           errmsg ("parse error '%U'", format_unformat_error, i);
14743           return -99;
14744         }
14745     }
14746
14747   if (!vec_len (name))
14748     {
14749       errmsg ("profile name must be specified");
14750       return -99;
14751     }
14752
14753   if (vec_len (name) > 64)
14754     {
14755       errmsg ("profile name too long");
14756       return -99;
14757     }
14758
14759   M (IKEV2_PROFILE_SET_TS, mp);
14760
14761   mp->is_local = is_local;
14762   mp->proto = (u8) proto;
14763   mp->start_port = (u16) start_port;
14764   mp->end_port = (u16) end_port;
14765   mp->start_addr = start_addr.as_u32;
14766   mp->end_addr = end_addr.as_u32;
14767   clib_memcpy (mp->name, name, vec_len (name));
14768   vec_free (name);
14769
14770   S (mp);
14771   W (ret);
14772   return ret;
14773 }
14774
14775 static int
14776 api_ikev2_set_local_key (vat_main_t * vam)
14777 {
14778   unformat_input_t *i = vam->input;
14779   vl_api_ikev2_set_local_key_t *mp;
14780   u8 *file = 0;
14781   int ret;
14782
14783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14784     {
14785       if (unformat (i, "file %v", &file))
14786         vec_add1 (file, 0);
14787       else
14788         {
14789           errmsg ("parse error '%U'", format_unformat_error, i);
14790           return -99;
14791         }
14792     }
14793
14794   if (!vec_len (file))
14795     {
14796       errmsg ("RSA key file must be specified");
14797       return -99;
14798     }
14799
14800   if (vec_len (file) > 256)
14801     {
14802       errmsg ("file name too long");
14803       return -99;
14804     }
14805
14806   M (IKEV2_SET_LOCAL_KEY, mp);
14807
14808   clib_memcpy (mp->key_file, file, vec_len (file));
14809   vec_free (file);
14810
14811   S (mp);
14812   W (ret);
14813   return ret;
14814 }
14815
14816 static int
14817 api_ikev2_set_responder (vat_main_t * vam)
14818 {
14819   unformat_input_t *i = vam->input;
14820   vl_api_ikev2_set_responder_t *mp;
14821   int ret;
14822   u8 *name = 0;
14823   u32 sw_if_index = ~0;
14824   ip4_address_t address;
14825
14826   const char *valid_chars = "a-zA-Z0-9_";
14827
14828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat
14831           (i, "%U interface %d address %U", unformat_token, valid_chars,
14832            &name, &sw_if_index, unformat_ip4_address, &address))
14833         vec_add1 (name, 0);
14834       else
14835         {
14836           errmsg ("parse error '%U'", format_unformat_error, i);
14837           return -99;
14838         }
14839     }
14840
14841   if (!vec_len (name))
14842     {
14843       errmsg ("profile name must be specified");
14844       return -99;
14845     }
14846
14847   if (vec_len (name) > 64)
14848     {
14849       errmsg ("profile name too long");
14850       return -99;
14851     }
14852
14853   M (IKEV2_SET_RESPONDER, mp);
14854
14855   clib_memcpy (mp->name, name, vec_len (name));
14856   vec_free (name);
14857
14858   mp->sw_if_index = sw_if_index;
14859   clib_memcpy (mp->address, &address, sizeof (address));
14860
14861   S (mp);
14862   W (ret);
14863   return ret;
14864 }
14865
14866 static int
14867 api_ikev2_set_ike_transforms (vat_main_t * vam)
14868 {
14869   unformat_input_t *i = vam->input;
14870   vl_api_ikev2_set_ike_transforms_t *mp;
14871   int ret;
14872   u8 *name = 0;
14873   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14874
14875   const char *valid_chars = "a-zA-Z0-9_";
14876
14877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14878     {
14879       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14880                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14881         vec_add1 (name, 0);
14882       else
14883         {
14884           errmsg ("parse error '%U'", format_unformat_error, i);
14885           return -99;
14886         }
14887     }
14888
14889   if (!vec_len (name))
14890     {
14891       errmsg ("profile name must be specified");
14892       return -99;
14893     }
14894
14895   if (vec_len (name) > 64)
14896     {
14897       errmsg ("profile name too long");
14898       return -99;
14899     }
14900
14901   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14902
14903   clib_memcpy (mp->name, name, vec_len (name));
14904   vec_free (name);
14905   mp->crypto_alg = crypto_alg;
14906   mp->crypto_key_size = crypto_key_size;
14907   mp->integ_alg = integ_alg;
14908   mp->dh_group = dh_group;
14909
14910   S (mp);
14911   W (ret);
14912   return ret;
14913 }
14914
14915
14916 static int
14917 api_ikev2_set_esp_transforms (vat_main_t * vam)
14918 {
14919   unformat_input_t *i = vam->input;
14920   vl_api_ikev2_set_esp_transforms_t *mp;
14921   int ret;
14922   u8 *name = 0;
14923   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14924
14925   const char *valid_chars = "a-zA-Z0-9_";
14926
14927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14928     {
14929       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14930                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14931         vec_add1 (name, 0);
14932       else
14933         {
14934           errmsg ("parse error '%U'", format_unformat_error, i);
14935           return -99;
14936         }
14937     }
14938
14939   if (!vec_len (name))
14940     {
14941       errmsg ("profile name must be specified");
14942       return -99;
14943     }
14944
14945   if (vec_len (name) > 64)
14946     {
14947       errmsg ("profile name too long");
14948       return -99;
14949     }
14950
14951   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14952
14953   clib_memcpy (mp->name, name, vec_len (name));
14954   vec_free (name);
14955   mp->crypto_alg = crypto_alg;
14956   mp->crypto_key_size = crypto_key_size;
14957   mp->integ_alg = integ_alg;
14958   mp->dh_group = dh_group;
14959
14960   S (mp);
14961   W (ret);
14962   return ret;
14963 }
14964
14965 static int
14966 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14967 {
14968   unformat_input_t *i = vam->input;
14969   vl_api_ikev2_set_sa_lifetime_t *mp;
14970   int ret;
14971   u8 *name = 0;
14972   u64 lifetime, lifetime_maxdata;
14973   u32 lifetime_jitter, handover;
14974
14975   const char *valid_chars = "a-zA-Z0-9_";
14976
14977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14980                     &lifetime, &lifetime_jitter, &handover,
14981                     &lifetime_maxdata))
14982         vec_add1 (name, 0);
14983       else
14984         {
14985           errmsg ("parse error '%U'", format_unformat_error, i);
14986           return -99;
14987         }
14988     }
14989
14990   if (!vec_len (name))
14991     {
14992       errmsg ("profile name must be specified");
14993       return -99;
14994     }
14995
14996   if (vec_len (name) > 64)
14997     {
14998       errmsg ("profile name too long");
14999       return -99;
15000     }
15001
15002   M (IKEV2_SET_SA_LIFETIME, mp);
15003
15004   clib_memcpy (mp->name, name, vec_len (name));
15005   vec_free (name);
15006   mp->lifetime = lifetime;
15007   mp->lifetime_jitter = lifetime_jitter;
15008   mp->handover = handover;
15009   mp->lifetime_maxdata = lifetime_maxdata;
15010
15011   S (mp);
15012   W (ret);
15013   return ret;
15014 }
15015
15016 static int
15017 api_ikev2_initiate_sa_init (vat_main_t * vam)
15018 {
15019   unformat_input_t *i = vam->input;
15020   vl_api_ikev2_initiate_sa_init_t *mp;
15021   int ret;
15022   u8 *name = 0;
15023
15024   const char *valid_chars = "a-zA-Z0-9_";
15025
15026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15027     {
15028       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15029         vec_add1 (name, 0);
15030       else
15031         {
15032           errmsg ("parse error '%U'", format_unformat_error, i);
15033           return -99;
15034         }
15035     }
15036
15037   if (!vec_len (name))
15038     {
15039       errmsg ("profile name must be specified");
15040       return -99;
15041     }
15042
15043   if (vec_len (name) > 64)
15044     {
15045       errmsg ("profile name too long");
15046       return -99;
15047     }
15048
15049   M (IKEV2_INITIATE_SA_INIT, mp);
15050
15051   clib_memcpy (mp->name, name, vec_len (name));
15052   vec_free (name);
15053
15054   S (mp);
15055   W (ret);
15056   return ret;
15057 }
15058
15059 static int
15060 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15061 {
15062   unformat_input_t *i = vam->input;
15063   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15064   int ret;
15065   u64 ispi;
15066
15067
15068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (i, "%lx", &ispi))
15071         ;
15072       else
15073         {
15074           errmsg ("parse error '%U'", format_unformat_error, i);
15075           return -99;
15076         }
15077     }
15078
15079   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15080
15081   mp->ispi = ispi;
15082
15083   S (mp);
15084   W (ret);
15085   return ret;
15086 }
15087
15088 static int
15089 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15090 {
15091   unformat_input_t *i = vam->input;
15092   vl_api_ikev2_initiate_del_child_sa_t *mp;
15093   int ret;
15094   u32 ispi;
15095
15096
15097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (i, "%x", &ispi))
15100         ;
15101       else
15102         {
15103           errmsg ("parse error '%U'", format_unformat_error, i);
15104           return -99;
15105         }
15106     }
15107
15108   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15109
15110   mp->ispi = ispi;
15111
15112   S (mp);
15113   W (ret);
15114   return ret;
15115 }
15116
15117 static int
15118 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15119 {
15120   unformat_input_t *i = vam->input;
15121   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15122   int ret;
15123   u32 ispi;
15124
15125
15126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (i, "%x", &ispi))
15129         ;
15130       else
15131         {
15132           errmsg ("parse error '%U'", format_unformat_error, i);
15133           return -99;
15134         }
15135     }
15136
15137   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15138
15139   mp->ispi = ispi;
15140
15141   S (mp);
15142   W (ret);
15143   return ret;
15144 }
15145
15146 /*
15147  * MAP
15148  */
15149 static int
15150 api_map_add_domain (vat_main_t * vam)
15151 {
15152   unformat_input_t *i = vam->input;
15153   vl_api_map_add_domain_t *mp;
15154
15155   ip4_address_t ip4_prefix;
15156   ip6_address_t ip6_prefix;
15157   ip6_address_t ip6_src;
15158   u32 num_m_args = 0;
15159   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15160     0, psid_length = 0;
15161   u8 is_translation = 0;
15162   u32 mtu = 0;
15163   u32 ip6_src_len = 128;
15164   int ret;
15165
15166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15167     {
15168       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15169                     &ip4_prefix, &ip4_prefix_len))
15170         num_m_args++;
15171       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15172                          &ip6_prefix, &ip6_prefix_len))
15173         num_m_args++;
15174       else
15175         if (unformat
15176             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15177              &ip6_src_len))
15178         num_m_args++;
15179       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15180         num_m_args++;
15181       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15182         num_m_args++;
15183       else if (unformat (i, "psid-offset %d", &psid_offset))
15184         num_m_args++;
15185       else if (unformat (i, "psid-len %d", &psid_length))
15186         num_m_args++;
15187       else if (unformat (i, "mtu %d", &mtu))
15188         num_m_args++;
15189       else if (unformat (i, "map-t"))
15190         is_translation = 1;
15191       else
15192         {
15193           clib_warning ("parse error '%U'", format_unformat_error, i);
15194           return -99;
15195         }
15196     }
15197
15198   if (num_m_args < 3)
15199     {
15200       errmsg ("mandatory argument(s) missing");
15201       return -99;
15202     }
15203
15204   /* Construct the API message */
15205   M (MAP_ADD_DOMAIN, mp);
15206
15207   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15208   mp->ip4_prefix_len = ip4_prefix_len;
15209
15210   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15211   mp->ip6_prefix_len = ip6_prefix_len;
15212
15213   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15214   mp->ip6_src_prefix_len = ip6_src_len;
15215
15216   mp->ea_bits_len = ea_bits_len;
15217   mp->psid_offset = psid_offset;
15218   mp->psid_length = psid_length;
15219   mp->is_translation = is_translation;
15220   mp->mtu = htons (mtu);
15221
15222   /* send it... */
15223   S (mp);
15224
15225   /* Wait for a reply, return good/bad news  */
15226   W (ret);
15227   return ret;
15228 }
15229
15230 static int
15231 api_map_del_domain (vat_main_t * vam)
15232 {
15233   unformat_input_t *i = vam->input;
15234   vl_api_map_del_domain_t *mp;
15235
15236   u32 num_m_args = 0;
15237   u32 index;
15238   int ret;
15239
15240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (i, "index %d", &index))
15243         num_m_args++;
15244       else
15245         {
15246           clib_warning ("parse error '%U'", format_unformat_error, i);
15247           return -99;
15248         }
15249     }
15250
15251   if (num_m_args != 1)
15252     {
15253       errmsg ("mandatory argument(s) missing");
15254       return -99;
15255     }
15256
15257   /* Construct the API message */
15258   M (MAP_DEL_DOMAIN, mp);
15259
15260   mp->index = ntohl (index);
15261
15262   /* send it... */
15263   S (mp);
15264
15265   /* Wait for a reply, return good/bad news  */
15266   W (ret);
15267   return ret;
15268 }
15269
15270 static int
15271 api_map_add_del_rule (vat_main_t * vam)
15272 {
15273   unformat_input_t *i = vam->input;
15274   vl_api_map_add_del_rule_t *mp;
15275   u8 is_add = 1;
15276   ip6_address_t ip6_dst;
15277   u32 num_m_args = 0, index, psid = 0;
15278   int ret;
15279
15280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15281     {
15282       if (unformat (i, "index %d", &index))
15283         num_m_args++;
15284       else if (unformat (i, "psid %d", &psid))
15285         num_m_args++;
15286       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15287         num_m_args++;
15288       else if (unformat (i, "del"))
15289         {
15290           is_add = 0;
15291         }
15292       else
15293         {
15294           clib_warning ("parse error '%U'", format_unformat_error, i);
15295           return -99;
15296         }
15297     }
15298
15299   /* Construct the API message */
15300   M (MAP_ADD_DEL_RULE, mp);
15301
15302   mp->index = ntohl (index);
15303   mp->is_add = is_add;
15304   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15305   mp->psid = ntohs (psid);
15306
15307   /* send it... */
15308   S (mp);
15309
15310   /* Wait for a reply, return good/bad news  */
15311   W (ret);
15312   return ret;
15313 }
15314
15315 static int
15316 api_map_domain_dump (vat_main_t * vam)
15317 {
15318   vl_api_map_domain_dump_t *mp;
15319   vl_api_control_ping_t *mp_ping;
15320   int ret;
15321
15322   /* Construct the API message */
15323   M (MAP_DOMAIN_DUMP, mp);
15324
15325   /* send it... */
15326   S (mp);
15327
15328   /* Use a control ping for synchronization */
15329   MPING (CONTROL_PING, mp_ping);
15330   S (mp_ping);
15331
15332   W (ret);
15333   return ret;
15334 }
15335
15336 static int
15337 api_map_rule_dump (vat_main_t * vam)
15338 {
15339   unformat_input_t *i = vam->input;
15340   vl_api_map_rule_dump_t *mp;
15341   vl_api_control_ping_t *mp_ping;
15342   u32 domain_index = ~0;
15343   int ret;
15344
15345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15346     {
15347       if (unformat (i, "index %u", &domain_index))
15348         ;
15349       else
15350         break;
15351     }
15352
15353   if (domain_index == ~0)
15354     {
15355       clib_warning ("parse error: domain index expected");
15356       return -99;
15357     }
15358
15359   /* Construct the API message */
15360   M (MAP_RULE_DUMP, mp);
15361
15362   mp->domain_index = htonl (domain_index);
15363
15364   /* send it... */
15365   S (mp);
15366
15367   /* Use a control ping for synchronization */
15368   MPING (CONTROL_PING, mp_ping);
15369   S (mp_ping);
15370
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static void vl_api_map_add_domain_reply_t_handler
15376   (vl_api_map_add_domain_reply_t * mp)
15377 {
15378   vat_main_t *vam = &vat_main;
15379   i32 retval = ntohl (mp->retval);
15380
15381   if (vam->async_mode)
15382     {
15383       vam->async_errors += (retval < 0);
15384     }
15385   else
15386     {
15387       vam->retval = retval;
15388       vam->result_ready = 1;
15389     }
15390 }
15391
15392 static void vl_api_map_add_domain_reply_t_handler_json
15393   (vl_api_map_add_domain_reply_t * mp)
15394 {
15395   vat_main_t *vam = &vat_main;
15396   vat_json_node_t node;
15397
15398   vat_json_init_object (&node);
15399   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15400   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15401
15402   vat_json_print (vam->ofp, &node);
15403   vat_json_free (&node);
15404
15405   vam->retval = ntohl (mp->retval);
15406   vam->result_ready = 1;
15407 }
15408
15409 static int
15410 api_get_first_msg_id (vat_main_t * vam)
15411 {
15412   vl_api_get_first_msg_id_t *mp;
15413   unformat_input_t *i = vam->input;
15414   u8 *name;
15415   u8 name_set = 0;
15416   int ret;
15417
15418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15419     {
15420       if (unformat (i, "client %s", &name))
15421         name_set = 1;
15422       else
15423         break;
15424     }
15425
15426   if (name_set == 0)
15427     {
15428       errmsg ("missing client name");
15429       return -99;
15430     }
15431   vec_add1 (name, 0);
15432
15433   if (vec_len (name) > 63)
15434     {
15435       errmsg ("client name too long");
15436       return -99;
15437     }
15438
15439   M (GET_FIRST_MSG_ID, mp);
15440   clib_memcpy (mp->name, name, vec_len (name));
15441   S (mp);
15442   W (ret);
15443   return ret;
15444 }
15445
15446 static int
15447 api_cop_interface_enable_disable (vat_main_t * vam)
15448 {
15449   unformat_input_t *line_input = vam->input;
15450   vl_api_cop_interface_enable_disable_t *mp;
15451   u32 sw_if_index = ~0;
15452   u8 enable_disable = 1;
15453   int ret;
15454
15455   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15456     {
15457       if (unformat (line_input, "disable"))
15458         enable_disable = 0;
15459       if (unformat (line_input, "enable"))
15460         enable_disable = 1;
15461       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15462                          vam, &sw_if_index))
15463         ;
15464       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15465         ;
15466       else
15467         break;
15468     }
15469
15470   if (sw_if_index == ~0)
15471     {
15472       errmsg ("missing interface name or sw_if_index");
15473       return -99;
15474     }
15475
15476   /* Construct the API message */
15477   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15478   mp->sw_if_index = ntohl (sw_if_index);
15479   mp->enable_disable = enable_disable;
15480
15481   /* send it... */
15482   S (mp);
15483   /* Wait for the reply */
15484   W (ret);
15485   return ret;
15486 }
15487
15488 static int
15489 api_cop_whitelist_enable_disable (vat_main_t * vam)
15490 {
15491   unformat_input_t *line_input = vam->input;
15492   vl_api_cop_whitelist_enable_disable_t *mp;
15493   u32 sw_if_index = ~0;
15494   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15495   u32 fib_id = 0;
15496   int ret;
15497
15498   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15499     {
15500       if (unformat (line_input, "ip4"))
15501         ip4 = 1;
15502       else if (unformat (line_input, "ip6"))
15503         ip6 = 1;
15504       else if (unformat (line_input, "default"))
15505         default_cop = 1;
15506       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15507                          vam, &sw_if_index))
15508         ;
15509       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15510         ;
15511       else if (unformat (line_input, "fib-id %d", &fib_id))
15512         ;
15513       else
15514         break;
15515     }
15516
15517   if (sw_if_index == ~0)
15518     {
15519       errmsg ("missing interface name or sw_if_index");
15520       return -99;
15521     }
15522
15523   /* Construct the API message */
15524   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15525   mp->sw_if_index = ntohl (sw_if_index);
15526   mp->fib_id = ntohl (fib_id);
15527   mp->ip4 = ip4;
15528   mp->ip6 = ip6;
15529   mp->default_cop = default_cop;
15530
15531   /* send it... */
15532   S (mp);
15533   /* Wait for the reply */
15534   W (ret);
15535   return ret;
15536 }
15537
15538 static int
15539 api_get_node_graph (vat_main_t * vam)
15540 {
15541   vl_api_get_node_graph_t *mp;
15542   int ret;
15543
15544   M (GET_NODE_GRAPH, mp);
15545
15546   /* send it... */
15547   S (mp);
15548   /* Wait for the reply */
15549   W (ret);
15550   return ret;
15551 }
15552
15553 /* *INDENT-OFF* */
15554 /** Used for parsing LISP eids */
15555 typedef CLIB_PACKED(struct{
15556   u8 addr[16];   /**< eid address */
15557   u32 len;       /**< prefix length if IP */
15558   u8 type;      /**< type of eid */
15559 }) lisp_eid_vat_t;
15560 /* *INDENT-ON* */
15561
15562 static uword
15563 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15564 {
15565   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15566
15567   memset (a, 0, sizeof (a[0]));
15568
15569   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15570     {
15571       a->type = 0;              /* ipv4 type */
15572     }
15573   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15574     {
15575       a->type = 1;              /* ipv6 type */
15576     }
15577   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15578     {
15579       a->type = 2;              /* mac type */
15580     }
15581   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15582     {
15583       a->type = 3;              /* NSH type */
15584       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15585       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15586     }
15587   else
15588     {
15589       return 0;
15590     }
15591
15592   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15593     {
15594       return 0;
15595     }
15596
15597   return 1;
15598 }
15599
15600 static int
15601 lisp_eid_size_vat (u8 type)
15602 {
15603   switch (type)
15604     {
15605     case 0:
15606       return 4;
15607     case 1:
15608       return 16;
15609     case 2:
15610       return 6;
15611     case 3:
15612       return 5;
15613     }
15614   return 0;
15615 }
15616
15617 static void
15618 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15619 {
15620   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15621 }
15622
15623 static int
15624 api_one_add_del_locator_set (vat_main_t * vam)
15625 {
15626   unformat_input_t *input = vam->input;
15627   vl_api_one_add_del_locator_set_t *mp;
15628   u8 is_add = 1;
15629   u8 *locator_set_name = NULL;
15630   u8 locator_set_name_set = 0;
15631   vl_api_local_locator_t locator, *locators = 0;
15632   u32 sw_if_index, priority, weight;
15633   u32 data_len = 0;
15634
15635   int ret;
15636   /* Parse args required to build the message */
15637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15638     {
15639       if (unformat (input, "del"))
15640         {
15641           is_add = 0;
15642         }
15643       else if (unformat (input, "locator-set %s", &locator_set_name))
15644         {
15645           locator_set_name_set = 1;
15646         }
15647       else if (unformat (input, "sw_if_index %u p %u w %u",
15648                          &sw_if_index, &priority, &weight))
15649         {
15650           locator.sw_if_index = htonl (sw_if_index);
15651           locator.priority = priority;
15652           locator.weight = weight;
15653           vec_add1 (locators, locator);
15654         }
15655       else
15656         if (unformat
15657             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15658              &sw_if_index, &priority, &weight))
15659         {
15660           locator.sw_if_index = htonl (sw_if_index);
15661           locator.priority = priority;
15662           locator.weight = weight;
15663           vec_add1 (locators, locator);
15664         }
15665       else
15666         break;
15667     }
15668
15669   if (locator_set_name_set == 0)
15670     {
15671       errmsg ("missing locator-set name");
15672       vec_free (locators);
15673       return -99;
15674     }
15675
15676   if (vec_len (locator_set_name) > 64)
15677     {
15678       errmsg ("locator-set name too long");
15679       vec_free (locator_set_name);
15680       vec_free (locators);
15681       return -99;
15682     }
15683   vec_add1 (locator_set_name, 0);
15684
15685   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15686
15687   /* Construct the API message */
15688   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15689
15690   mp->is_add = is_add;
15691   clib_memcpy (mp->locator_set_name, locator_set_name,
15692                vec_len (locator_set_name));
15693   vec_free (locator_set_name);
15694
15695   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15696   if (locators)
15697     clib_memcpy (mp->locators, locators, data_len);
15698   vec_free (locators);
15699
15700   /* send it... */
15701   S (mp);
15702
15703   /* Wait for a reply... */
15704   W (ret);
15705   return ret;
15706 }
15707
15708 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15709
15710 static int
15711 api_one_add_del_locator (vat_main_t * vam)
15712 {
15713   unformat_input_t *input = vam->input;
15714   vl_api_one_add_del_locator_t *mp;
15715   u32 tmp_if_index = ~0;
15716   u32 sw_if_index = ~0;
15717   u8 sw_if_index_set = 0;
15718   u8 sw_if_index_if_name_set = 0;
15719   u32 priority = ~0;
15720   u8 priority_set = 0;
15721   u32 weight = ~0;
15722   u8 weight_set = 0;
15723   u8 is_add = 1;
15724   u8 *locator_set_name = NULL;
15725   u8 locator_set_name_set = 0;
15726   int ret;
15727
15728   /* Parse args required to build the message */
15729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15730     {
15731       if (unformat (input, "del"))
15732         {
15733           is_add = 0;
15734         }
15735       else if (unformat (input, "locator-set %s", &locator_set_name))
15736         {
15737           locator_set_name_set = 1;
15738         }
15739       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15740                          &tmp_if_index))
15741         {
15742           sw_if_index_if_name_set = 1;
15743           sw_if_index = tmp_if_index;
15744         }
15745       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15746         {
15747           sw_if_index_set = 1;
15748           sw_if_index = tmp_if_index;
15749         }
15750       else if (unformat (input, "p %d", &priority))
15751         {
15752           priority_set = 1;
15753         }
15754       else if (unformat (input, "w %d", &weight))
15755         {
15756           weight_set = 1;
15757         }
15758       else
15759         break;
15760     }
15761
15762   if (locator_set_name_set == 0)
15763     {
15764       errmsg ("missing locator-set name");
15765       return -99;
15766     }
15767
15768   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15769     {
15770       errmsg ("missing sw_if_index");
15771       vec_free (locator_set_name);
15772       return -99;
15773     }
15774
15775   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15776     {
15777       errmsg ("cannot use both params interface name and sw_if_index");
15778       vec_free (locator_set_name);
15779       return -99;
15780     }
15781
15782   if (priority_set == 0)
15783     {
15784       errmsg ("missing locator-set priority");
15785       vec_free (locator_set_name);
15786       return -99;
15787     }
15788
15789   if (weight_set == 0)
15790     {
15791       errmsg ("missing locator-set weight");
15792       vec_free (locator_set_name);
15793       return -99;
15794     }
15795
15796   if (vec_len (locator_set_name) > 64)
15797     {
15798       errmsg ("locator-set name too long");
15799       vec_free (locator_set_name);
15800       return -99;
15801     }
15802   vec_add1 (locator_set_name, 0);
15803
15804   /* Construct the API message */
15805   M (ONE_ADD_DEL_LOCATOR, mp);
15806
15807   mp->is_add = is_add;
15808   mp->sw_if_index = ntohl (sw_if_index);
15809   mp->priority = priority;
15810   mp->weight = weight;
15811   clib_memcpy (mp->locator_set_name, locator_set_name,
15812                vec_len (locator_set_name));
15813   vec_free (locator_set_name);
15814
15815   /* send it... */
15816   S (mp);
15817
15818   /* Wait for a reply... */
15819   W (ret);
15820   return ret;
15821 }
15822
15823 #define api_lisp_add_del_locator api_one_add_del_locator
15824
15825 uword
15826 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15827 {
15828   u32 *key_id = va_arg (*args, u32 *);
15829   u8 *s = 0;
15830
15831   if (unformat (input, "%s", &s))
15832     {
15833       if (!strcmp ((char *) s, "sha1"))
15834         key_id[0] = HMAC_SHA_1_96;
15835       else if (!strcmp ((char *) s, "sha256"))
15836         key_id[0] = HMAC_SHA_256_128;
15837       else
15838         {
15839           clib_warning ("invalid key_id: '%s'", s);
15840           key_id[0] = HMAC_NO_KEY;
15841         }
15842     }
15843   else
15844     return 0;
15845
15846   vec_free (s);
15847   return 1;
15848 }
15849
15850 static int
15851 api_one_add_del_local_eid (vat_main_t * vam)
15852 {
15853   unformat_input_t *input = vam->input;
15854   vl_api_one_add_del_local_eid_t *mp;
15855   u8 is_add = 1;
15856   u8 eid_set = 0;
15857   lisp_eid_vat_t _eid, *eid = &_eid;
15858   u8 *locator_set_name = 0;
15859   u8 locator_set_name_set = 0;
15860   u32 vni = 0;
15861   u16 key_id = 0;
15862   u8 *key = 0;
15863   int ret;
15864
15865   /* Parse args required to build the message */
15866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15867     {
15868       if (unformat (input, "del"))
15869         {
15870           is_add = 0;
15871         }
15872       else if (unformat (input, "vni %d", &vni))
15873         {
15874           ;
15875         }
15876       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15877         {
15878           eid_set = 1;
15879         }
15880       else if (unformat (input, "locator-set %s", &locator_set_name))
15881         {
15882           locator_set_name_set = 1;
15883         }
15884       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15885         ;
15886       else if (unformat (input, "secret-key %_%v%_", &key))
15887         ;
15888       else
15889         break;
15890     }
15891
15892   if (locator_set_name_set == 0)
15893     {
15894       errmsg ("missing locator-set name");
15895       return -99;
15896     }
15897
15898   if (0 == eid_set)
15899     {
15900       errmsg ("EID address not set!");
15901       vec_free (locator_set_name);
15902       return -99;
15903     }
15904
15905   if (key && (0 == key_id))
15906     {
15907       errmsg ("invalid key_id!");
15908       return -99;
15909     }
15910
15911   if (vec_len (key) > 64)
15912     {
15913       errmsg ("key too long");
15914       vec_free (key);
15915       return -99;
15916     }
15917
15918   if (vec_len (locator_set_name) > 64)
15919     {
15920       errmsg ("locator-set name too long");
15921       vec_free (locator_set_name);
15922       return -99;
15923     }
15924   vec_add1 (locator_set_name, 0);
15925
15926   /* Construct the API message */
15927   M (ONE_ADD_DEL_LOCAL_EID, mp);
15928
15929   mp->is_add = is_add;
15930   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15931   mp->eid_type = eid->type;
15932   mp->prefix_len = eid->len;
15933   mp->vni = clib_host_to_net_u32 (vni);
15934   mp->key_id = clib_host_to_net_u16 (key_id);
15935   clib_memcpy (mp->locator_set_name, locator_set_name,
15936                vec_len (locator_set_name));
15937   clib_memcpy (mp->key, key, vec_len (key));
15938
15939   vec_free (locator_set_name);
15940   vec_free (key);
15941
15942   /* send it... */
15943   S (mp);
15944
15945   /* Wait for a reply... */
15946   W (ret);
15947   return ret;
15948 }
15949
15950 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15951
15952 static int
15953 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15954 {
15955   u32 dp_table = 0, vni = 0;;
15956   unformat_input_t *input = vam->input;
15957   vl_api_gpe_add_del_fwd_entry_t *mp;
15958   u8 is_add = 1;
15959   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15960   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15961   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15962   u32 action = ~0, w;
15963   ip4_address_t rmt_rloc4, lcl_rloc4;
15964   ip6_address_t rmt_rloc6, lcl_rloc6;
15965   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15966   int ret;
15967
15968   memset (&rloc, 0, sizeof (rloc));
15969
15970   /* Parse args required to build the message */
15971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15972     {
15973       if (unformat (input, "del"))
15974         is_add = 0;
15975       else if (unformat (input, "add"))
15976         is_add = 1;
15977       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15978         {
15979           rmt_eid_set = 1;
15980         }
15981       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15982         {
15983           lcl_eid_set = 1;
15984         }
15985       else if (unformat (input, "vrf %d", &dp_table))
15986         ;
15987       else if (unformat (input, "bd %d", &dp_table))
15988         ;
15989       else if (unformat (input, "vni %d", &vni))
15990         ;
15991       else if (unformat (input, "w %d", &w))
15992         {
15993           if (!curr_rloc)
15994             {
15995               errmsg ("No RLOC configured for setting priority/weight!");
15996               return -99;
15997             }
15998           curr_rloc->weight = w;
15999         }
16000       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16001                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16002         {
16003           rloc.is_ip4 = 1;
16004
16005           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16006           rloc.weight = 0;
16007           vec_add1 (lcl_locs, rloc);
16008
16009           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16010           vec_add1 (rmt_locs, rloc);
16011           /* weight saved in rmt loc */
16012           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16013         }
16014       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16015                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16016         {
16017           rloc.is_ip4 = 0;
16018           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16019           rloc.weight = 0;
16020           vec_add1 (lcl_locs, rloc);
16021
16022           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16023           vec_add1 (rmt_locs, rloc);
16024           /* weight saved in rmt loc */
16025           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16026         }
16027       else if (unformat (input, "action %d", &action))
16028         {
16029           ;
16030         }
16031       else
16032         {
16033           clib_warning ("parse error '%U'", format_unformat_error, input);
16034           return -99;
16035         }
16036     }
16037
16038   if (!rmt_eid_set)
16039     {
16040       errmsg ("remote eid addresses not set");
16041       return -99;
16042     }
16043
16044   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16045     {
16046       errmsg ("eid types don't match");
16047       return -99;
16048     }
16049
16050   if (0 == rmt_locs && (u32) ~ 0 == action)
16051     {
16052       errmsg ("action not set for negative mapping");
16053       return -99;
16054     }
16055
16056   /* Construct the API message */
16057   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16058       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16059
16060   mp->is_add = is_add;
16061   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16062   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16063   mp->eid_type = rmt_eid->type;
16064   mp->dp_table = clib_host_to_net_u32 (dp_table);
16065   mp->vni = clib_host_to_net_u32 (vni);
16066   mp->rmt_len = rmt_eid->len;
16067   mp->lcl_len = lcl_eid->len;
16068   mp->action = action;
16069
16070   if (0 != rmt_locs && 0 != lcl_locs)
16071     {
16072       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16073       clib_memcpy (mp->locs, lcl_locs,
16074                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16075
16076       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16077       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16078                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16079     }
16080   vec_free (lcl_locs);
16081   vec_free (rmt_locs);
16082
16083   /* send it... */
16084   S (mp);
16085
16086   /* Wait for a reply... */
16087   W (ret);
16088   return ret;
16089 }
16090
16091 static int
16092 api_one_add_del_map_server (vat_main_t * vam)
16093 {
16094   unformat_input_t *input = vam->input;
16095   vl_api_one_add_del_map_server_t *mp;
16096   u8 is_add = 1;
16097   u8 ipv4_set = 0;
16098   u8 ipv6_set = 0;
16099   ip4_address_t ipv4;
16100   ip6_address_t ipv6;
16101   int ret;
16102
16103   /* Parse args required to build the message */
16104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (input, "del"))
16107         {
16108           is_add = 0;
16109         }
16110       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16111         {
16112           ipv4_set = 1;
16113         }
16114       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16115         {
16116           ipv6_set = 1;
16117         }
16118       else
16119         break;
16120     }
16121
16122   if (ipv4_set && ipv6_set)
16123     {
16124       errmsg ("both eid v4 and v6 addresses set");
16125       return -99;
16126     }
16127
16128   if (!ipv4_set && !ipv6_set)
16129     {
16130       errmsg ("eid addresses not set");
16131       return -99;
16132     }
16133
16134   /* Construct the API message */
16135   M (ONE_ADD_DEL_MAP_SERVER, mp);
16136
16137   mp->is_add = is_add;
16138   if (ipv6_set)
16139     {
16140       mp->is_ipv6 = 1;
16141       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16142     }
16143   else
16144     {
16145       mp->is_ipv6 = 0;
16146       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16147     }
16148
16149   /* send it... */
16150   S (mp);
16151
16152   /* Wait for a reply... */
16153   W (ret);
16154   return ret;
16155 }
16156
16157 #define api_lisp_add_del_map_server api_one_add_del_map_server
16158
16159 static int
16160 api_one_add_del_map_resolver (vat_main_t * vam)
16161 {
16162   unformat_input_t *input = vam->input;
16163   vl_api_one_add_del_map_resolver_t *mp;
16164   u8 is_add = 1;
16165   u8 ipv4_set = 0;
16166   u8 ipv6_set = 0;
16167   ip4_address_t ipv4;
16168   ip6_address_t ipv6;
16169   int ret;
16170
16171   /* Parse args required to build the message */
16172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16173     {
16174       if (unformat (input, "del"))
16175         {
16176           is_add = 0;
16177         }
16178       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16179         {
16180           ipv4_set = 1;
16181         }
16182       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16183         {
16184           ipv6_set = 1;
16185         }
16186       else
16187         break;
16188     }
16189
16190   if (ipv4_set && ipv6_set)
16191     {
16192       errmsg ("both eid v4 and v6 addresses set");
16193       return -99;
16194     }
16195
16196   if (!ipv4_set && !ipv6_set)
16197     {
16198       errmsg ("eid addresses not set");
16199       return -99;
16200     }
16201
16202   /* Construct the API message */
16203   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16204
16205   mp->is_add = is_add;
16206   if (ipv6_set)
16207     {
16208       mp->is_ipv6 = 1;
16209       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16210     }
16211   else
16212     {
16213       mp->is_ipv6 = 0;
16214       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16215     }
16216
16217   /* send it... */
16218   S (mp);
16219
16220   /* Wait for a reply... */
16221   W (ret);
16222   return ret;
16223 }
16224
16225 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16226
16227 static int
16228 api_lisp_gpe_enable_disable (vat_main_t * vam)
16229 {
16230   unformat_input_t *input = vam->input;
16231   vl_api_gpe_enable_disable_t *mp;
16232   u8 is_set = 0;
16233   u8 is_en = 1;
16234   int ret;
16235
16236   /* Parse args required to build the message */
16237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16238     {
16239       if (unformat (input, "enable"))
16240         {
16241           is_set = 1;
16242           is_en = 1;
16243         }
16244       else if (unformat (input, "disable"))
16245         {
16246           is_set = 1;
16247           is_en = 0;
16248         }
16249       else
16250         break;
16251     }
16252
16253   if (is_set == 0)
16254     {
16255       errmsg ("Value not set");
16256       return -99;
16257     }
16258
16259   /* Construct the API message */
16260   M (GPE_ENABLE_DISABLE, mp);
16261
16262   mp->is_en = is_en;
16263
16264   /* send it... */
16265   S (mp);
16266
16267   /* Wait for a reply... */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 static int
16273 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16274 {
16275   unformat_input_t *input = vam->input;
16276   vl_api_one_rloc_probe_enable_disable_t *mp;
16277   u8 is_set = 0;
16278   u8 is_en = 0;
16279   int ret;
16280
16281   /* Parse args required to build the message */
16282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16283     {
16284       if (unformat (input, "enable"))
16285         {
16286           is_set = 1;
16287           is_en = 1;
16288         }
16289       else if (unformat (input, "disable"))
16290         is_set = 1;
16291       else
16292         break;
16293     }
16294
16295   if (!is_set)
16296     {
16297       errmsg ("Value not set");
16298       return -99;
16299     }
16300
16301   /* Construct the API message */
16302   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16303
16304   mp->is_enabled = is_en;
16305
16306   /* send it... */
16307   S (mp);
16308
16309   /* Wait for a reply... */
16310   W (ret);
16311   return ret;
16312 }
16313
16314 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16315
16316 static int
16317 api_one_map_register_enable_disable (vat_main_t * vam)
16318 {
16319   unformat_input_t *input = vam->input;
16320   vl_api_one_map_register_enable_disable_t *mp;
16321   u8 is_set = 0;
16322   u8 is_en = 0;
16323   int ret;
16324
16325   /* Parse args required to build the message */
16326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16327     {
16328       if (unformat (input, "enable"))
16329         {
16330           is_set = 1;
16331           is_en = 1;
16332         }
16333       else if (unformat (input, "disable"))
16334         is_set = 1;
16335       else
16336         break;
16337     }
16338
16339   if (!is_set)
16340     {
16341       errmsg ("Value not set");
16342       return -99;
16343     }
16344
16345   /* Construct the API message */
16346   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16347
16348   mp->is_enabled = is_en;
16349
16350   /* send it... */
16351   S (mp);
16352
16353   /* Wait for a reply... */
16354   W (ret);
16355   return ret;
16356 }
16357
16358 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16359
16360 static int
16361 api_one_enable_disable (vat_main_t * vam)
16362 {
16363   unformat_input_t *input = vam->input;
16364   vl_api_one_enable_disable_t *mp;
16365   u8 is_set = 0;
16366   u8 is_en = 0;
16367   int ret;
16368
16369   /* Parse args required to build the message */
16370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16371     {
16372       if (unformat (input, "enable"))
16373         {
16374           is_set = 1;
16375           is_en = 1;
16376         }
16377       else if (unformat (input, "disable"))
16378         {
16379           is_set = 1;
16380         }
16381       else
16382         break;
16383     }
16384
16385   if (!is_set)
16386     {
16387       errmsg ("Value not set");
16388       return -99;
16389     }
16390
16391   /* Construct the API message */
16392   M (ONE_ENABLE_DISABLE, mp);
16393
16394   mp->is_en = is_en;
16395
16396   /* send it... */
16397   S (mp);
16398
16399   /* Wait for a reply... */
16400   W (ret);
16401   return ret;
16402 }
16403
16404 #define api_lisp_enable_disable api_one_enable_disable
16405
16406 static int
16407 api_show_one_map_register_state (vat_main_t * vam)
16408 {
16409   vl_api_show_one_map_register_state_t *mp;
16410   int ret;
16411
16412   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16413
16414   /* send */
16415   S (mp);
16416
16417   /* wait for reply */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 #define api_show_lisp_map_register_state api_show_one_map_register_state
16423
16424 static int
16425 api_show_one_rloc_probe_state (vat_main_t * vam)
16426 {
16427   vl_api_show_one_rloc_probe_state_t *mp;
16428   int ret;
16429
16430   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16431
16432   /* send */
16433   S (mp);
16434
16435   /* wait for reply */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16441
16442 static int
16443 api_one_add_del_ndp_entry (vat_main_t * vam)
16444 {
16445   vl_api_one_add_del_ndp_entry_t *mp;
16446   unformat_input_t *input = vam->input;
16447   u8 is_add = 1;
16448   u8 mac_set = 0;
16449   u8 bd_set = 0;
16450   u8 ip_set = 0;
16451   u8 mac[6] = { 0, };
16452   u8 ip6[16] = { 0, };
16453   u32 bd = ~0;
16454   int ret;
16455
16456   /* Parse args required to build the message */
16457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16458     {
16459       if (unformat (input, "del"))
16460         is_add = 0;
16461       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16462         mac_set = 1;
16463       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16464         ip_set = 1;
16465       else if (unformat (input, "bd %d", &bd))
16466         bd_set = 1;
16467       else
16468         {
16469           errmsg ("parse error '%U'", format_unformat_error, input);
16470           return -99;
16471         }
16472     }
16473
16474   if (!bd_set || !ip_set || (!mac_set && is_add))
16475     {
16476       errmsg ("Missing BD, IP or MAC!");
16477       return -99;
16478     }
16479
16480   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16481   mp->is_add = is_add;
16482   clib_memcpy (mp->mac, mac, 6);
16483   mp->bd = clib_host_to_net_u32 (bd);
16484   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16485
16486   /* send */
16487   S (mp);
16488
16489   /* wait for reply */
16490   W (ret);
16491   return ret;
16492 }
16493
16494 static int
16495 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16496 {
16497   vl_api_one_add_del_l2_arp_entry_t *mp;
16498   unformat_input_t *input = vam->input;
16499   u8 is_add = 1;
16500   u8 mac_set = 0;
16501   u8 bd_set = 0;
16502   u8 ip_set = 0;
16503   u8 mac[6] = { 0, };
16504   u32 ip4 = 0, bd = ~0;
16505   int ret;
16506
16507   /* Parse args required to build the message */
16508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16509     {
16510       if (unformat (input, "del"))
16511         is_add = 0;
16512       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16513         mac_set = 1;
16514       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16515         ip_set = 1;
16516       else if (unformat (input, "bd %d", &bd))
16517         bd_set = 1;
16518       else
16519         {
16520           errmsg ("parse error '%U'", format_unformat_error, input);
16521           return -99;
16522         }
16523     }
16524
16525   if (!bd_set || !ip_set || (!mac_set && is_add))
16526     {
16527       errmsg ("Missing BD, IP or MAC!");
16528       return -99;
16529     }
16530
16531   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16532   mp->is_add = is_add;
16533   clib_memcpy (mp->mac, mac, 6);
16534   mp->bd = clib_host_to_net_u32 (bd);
16535   mp->ip4 = ip4;
16536
16537   /* send */
16538   S (mp);
16539
16540   /* wait for reply */
16541   W (ret);
16542   return ret;
16543 }
16544
16545 static int
16546 api_one_ndp_bd_get (vat_main_t * vam)
16547 {
16548   vl_api_one_ndp_bd_get_t *mp;
16549   int ret;
16550
16551   M (ONE_NDP_BD_GET, mp);
16552
16553   /* send */
16554   S (mp);
16555
16556   /* wait for reply */
16557   W (ret);
16558   return ret;
16559 }
16560
16561 static int
16562 api_one_ndp_entries_get (vat_main_t * vam)
16563 {
16564   vl_api_one_ndp_entries_get_t *mp;
16565   unformat_input_t *input = vam->input;
16566   u8 bd_set = 0;
16567   u32 bd = ~0;
16568   int ret;
16569
16570   /* Parse args required to build the message */
16571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (input, "bd %d", &bd))
16574         bd_set = 1;
16575       else
16576         {
16577           errmsg ("parse error '%U'", format_unformat_error, input);
16578           return -99;
16579         }
16580     }
16581
16582   if (!bd_set)
16583     {
16584       errmsg ("Expected bridge domain!");
16585       return -99;
16586     }
16587
16588   M (ONE_NDP_ENTRIES_GET, mp);
16589   mp->bd = clib_host_to_net_u32 (bd);
16590
16591   /* send */
16592   S (mp);
16593
16594   /* wait for reply */
16595   W (ret);
16596   return ret;
16597 }
16598
16599 static int
16600 api_one_l2_arp_bd_get (vat_main_t * vam)
16601 {
16602   vl_api_one_l2_arp_bd_get_t *mp;
16603   int ret;
16604
16605   M (ONE_L2_ARP_BD_GET, mp);
16606
16607   /* send */
16608   S (mp);
16609
16610   /* wait for reply */
16611   W (ret);
16612   return ret;
16613 }
16614
16615 static int
16616 api_one_l2_arp_entries_get (vat_main_t * vam)
16617 {
16618   vl_api_one_l2_arp_entries_get_t *mp;
16619   unformat_input_t *input = vam->input;
16620   u8 bd_set = 0;
16621   u32 bd = ~0;
16622   int ret;
16623
16624   /* Parse args required to build the message */
16625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16626     {
16627       if (unformat (input, "bd %d", &bd))
16628         bd_set = 1;
16629       else
16630         {
16631           errmsg ("parse error '%U'", format_unformat_error, input);
16632           return -99;
16633         }
16634     }
16635
16636   if (!bd_set)
16637     {
16638       errmsg ("Expected bridge domain!");
16639       return -99;
16640     }
16641
16642   M (ONE_L2_ARP_ENTRIES_GET, mp);
16643   mp->bd = clib_host_to_net_u32 (bd);
16644
16645   /* send */
16646   S (mp);
16647
16648   /* wait for reply */
16649   W (ret);
16650   return ret;
16651 }
16652
16653 static int
16654 api_one_stats_enable_disable (vat_main_t * vam)
16655 {
16656   vl_api_one_stats_enable_disable_t *mp;
16657   unformat_input_t *input = vam->input;
16658   u8 is_set = 0;
16659   u8 is_en = 0;
16660   int ret;
16661
16662   /* Parse args required to build the message */
16663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16664     {
16665       if (unformat (input, "enable"))
16666         {
16667           is_set = 1;
16668           is_en = 1;
16669         }
16670       else if (unformat (input, "disable"))
16671         {
16672           is_set = 1;
16673         }
16674       else
16675         break;
16676     }
16677
16678   if (!is_set)
16679     {
16680       errmsg ("Value not set");
16681       return -99;
16682     }
16683
16684   M (ONE_STATS_ENABLE_DISABLE, mp);
16685   mp->is_en = is_en;
16686
16687   /* send */
16688   S (mp);
16689
16690   /* wait for reply */
16691   W (ret);
16692   return ret;
16693 }
16694
16695 static int
16696 api_show_one_stats_enable_disable (vat_main_t * vam)
16697 {
16698   vl_api_show_one_stats_enable_disable_t *mp;
16699   int ret;
16700
16701   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16702
16703   /* send */
16704   S (mp);
16705
16706   /* wait for reply */
16707   W (ret);
16708   return ret;
16709 }
16710
16711 static int
16712 api_show_one_map_request_mode (vat_main_t * vam)
16713 {
16714   vl_api_show_one_map_request_mode_t *mp;
16715   int ret;
16716
16717   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16718
16719   /* send */
16720   S (mp);
16721
16722   /* wait for reply */
16723   W (ret);
16724   return ret;
16725 }
16726
16727 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16728
16729 static int
16730 api_one_map_request_mode (vat_main_t * vam)
16731 {
16732   unformat_input_t *input = vam->input;
16733   vl_api_one_map_request_mode_t *mp;
16734   u8 mode = 0;
16735   int ret;
16736
16737   /* Parse args required to build the message */
16738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16739     {
16740       if (unformat (input, "dst-only"))
16741         mode = 0;
16742       else if (unformat (input, "src-dst"))
16743         mode = 1;
16744       else
16745         {
16746           errmsg ("parse error '%U'", format_unformat_error, input);
16747           return -99;
16748         }
16749     }
16750
16751   M (ONE_MAP_REQUEST_MODE, mp);
16752
16753   mp->mode = mode;
16754
16755   /* send */
16756   S (mp);
16757
16758   /* wait for reply */
16759   W (ret);
16760   return ret;
16761 }
16762
16763 #define api_lisp_map_request_mode api_one_map_request_mode
16764
16765 /**
16766  * Enable/disable ONE proxy ITR.
16767  *
16768  * @param vam vpp API test context
16769  * @return return code
16770  */
16771 static int
16772 api_one_pitr_set_locator_set (vat_main_t * vam)
16773 {
16774   u8 ls_name_set = 0;
16775   unformat_input_t *input = vam->input;
16776   vl_api_one_pitr_set_locator_set_t *mp;
16777   u8 is_add = 1;
16778   u8 *ls_name = 0;
16779   int ret;
16780
16781   /* Parse args required to build the message */
16782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16783     {
16784       if (unformat (input, "del"))
16785         is_add = 0;
16786       else if (unformat (input, "locator-set %s", &ls_name))
16787         ls_name_set = 1;
16788       else
16789         {
16790           errmsg ("parse error '%U'", format_unformat_error, input);
16791           return -99;
16792         }
16793     }
16794
16795   if (!ls_name_set)
16796     {
16797       errmsg ("locator-set name not set!");
16798       return -99;
16799     }
16800
16801   M (ONE_PITR_SET_LOCATOR_SET, mp);
16802
16803   mp->is_add = is_add;
16804   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16805   vec_free (ls_name);
16806
16807   /* send */
16808   S (mp);
16809
16810   /* wait for reply */
16811   W (ret);
16812   return ret;
16813 }
16814
16815 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16816
16817 static int
16818 api_one_nsh_set_locator_set (vat_main_t * vam)
16819 {
16820   u8 ls_name_set = 0;
16821   unformat_input_t *input = vam->input;
16822   vl_api_one_nsh_set_locator_set_t *mp;
16823   u8 is_add = 1;
16824   u8 *ls_name = 0;
16825   int ret;
16826
16827   /* Parse args required to build the message */
16828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16829     {
16830       if (unformat (input, "del"))
16831         is_add = 0;
16832       else if (unformat (input, "ls %s", &ls_name))
16833         ls_name_set = 1;
16834       else
16835         {
16836           errmsg ("parse error '%U'", format_unformat_error, input);
16837           return -99;
16838         }
16839     }
16840
16841   if (!ls_name_set && is_add)
16842     {
16843       errmsg ("locator-set name not set!");
16844       return -99;
16845     }
16846
16847   M (ONE_NSH_SET_LOCATOR_SET, mp);
16848
16849   mp->is_add = is_add;
16850   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16851   vec_free (ls_name);
16852
16853   /* send */
16854   S (mp);
16855
16856   /* wait for reply */
16857   W (ret);
16858   return ret;
16859 }
16860
16861 static int
16862 api_show_one_pitr (vat_main_t * vam)
16863 {
16864   vl_api_show_one_pitr_t *mp;
16865   int ret;
16866
16867   if (!vam->json_output)
16868     {
16869       print (vam->ofp, "%=20s", "lisp status:");
16870     }
16871
16872   M (SHOW_ONE_PITR, mp);
16873   /* send it... */
16874   S (mp);
16875
16876   /* Wait for a reply... */
16877   W (ret);
16878   return ret;
16879 }
16880
16881 #define api_show_lisp_pitr api_show_one_pitr
16882
16883 static int
16884 api_one_use_petr (vat_main_t * vam)
16885 {
16886   unformat_input_t *input = vam->input;
16887   vl_api_one_use_petr_t *mp;
16888   u8 is_add = 0;
16889   ip_address_t ip;
16890   int ret;
16891
16892   memset (&ip, 0, sizeof (ip));
16893
16894   /* Parse args required to build the message */
16895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (input, "disable"))
16898         is_add = 0;
16899       else
16900         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16901         {
16902           is_add = 1;
16903           ip_addr_version (&ip) = IP4;
16904         }
16905       else
16906         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16907         {
16908           is_add = 1;
16909           ip_addr_version (&ip) = IP6;
16910         }
16911       else
16912         {
16913           errmsg ("parse error '%U'", format_unformat_error, input);
16914           return -99;
16915         }
16916     }
16917
16918   M (ONE_USE_PETR, mp);
16919
16920   mp->is_add = is_add;
16921   if (is_add)
16922     {
16923       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16924       if (mp->is_ip4)
16925         clib_memcpy (mp->address, &ip, 4);
16926       else
16927         clib_memcpy (mp->address, &ip, 16);
16928     }
16929
16930   /* send */
16931   S (mp);
16932
16933   /* wait for reply */
16934   W (ret);
16935   return ret;
16936 }
16937
16938 #define api_lisp_use_petr api_one_use_petr
16939
16940 static int
16941 api_show_one_nsh_mapping (vat_main_t * vam)
16942 {
16943   vl_api_show_one_use_petr_t *mp;
16944   int ret;
16945
16946   if (!vam->json_output)
16947     {
16948       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16949     }
16950
16951   M (SHOW_ONE_NSH_MAPPING, mp);
16952   /* send it... */
16953   S (mp);
16954
16955   /* Wait for a reply... */
16956   W (ret);
16957   return ret;
16958 }
16959
16960 static int
16961 api_show_one_use_petr (vat_main_t * vam)
16962 {
16963   vl_api_show_one_use_petr_t *mp;
16964   int ret;
16965
16966   if (!vam->json_output)
16967     {
16968       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16969     }
16970
16971   M (SHOW_ONE_USE_PETR, mp);
16972   /* send it... */
16973   S (mp);
16974
16975   /* Wait for a reply... */
16976   W (ret);
16977   return ret;
16978 }
16979
16980 #define api_show_lisp_use_petr api_show_one_use_petr
16981
16982 /**
16983  * Add/delete mapping between vni and vrf
16984  */
16985 static int
16986 api_one_eid_table_add_del_map (vat_main_t * vam)
16987 {
16988   unformat_input_t *input = vam->input;
16989   vl_api_one_eid_table_add_del_map_t *mp;
16990   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16991   u32 vni, vrf, bd_index;
16992   int ret;
16993
16994   /* Parse args required to build the message */
16995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16996     {
16997       if (unformat (input, "del"))
16998         is_add = 0;
16999       else if (unformat (input, "vrf %d", &vrf))
17000         vrf_set = 1;
17001       else if (unformat (input, "bd_index %d", &bd_index))
17002         bd_index_set = 1;
17003       else if (unformat (input, "vni %d", &vni))
17004         vni_set = 1;
17005       else
17006         break;
17007     }
17008
17009   if (!vni_set || (!vrf_set && !bd_index_set))
17010     {
17011       errmsg ("missing arguments!");
17012       return -99;
17013     }
17014
17015   if (vrf_set && bd_index_set)
17016     {
17017       errmsg ("error: both vrf and bd entered!");
17018       return -99;
17019     }
17020
17021   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17022
17023   mp->is_add = is_add;
17024   mp->vni = htonl (vni);
17025   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17026   mp->is_l2 = bd_index_set;
17027
17028   /* send */
17029   S (mp);
17030
17031   /* wait for reply */
17032   W (ret);
17033   return ret;
17034 }
17035
17036 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17037
17038 uword
17039 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17040 {
17041   u32 *action = va_arg (*args, u32 *);
17042   u8 *s = 0;
17043
17044   if (unformat (input, "%s", &s))
17045     {
17046       if (!strcmp ((char *) s, "no-action"))
17047         action[0] = 0;
17048       else if (!strcmp ((char *) s, "natively-forward"))
17049         action[0] = 1;
17050       else if (!strcmp ((char *) s, "send-map-request"))
17051         action[0] = 2;
17052       else if (!strcmp ((char *) s, "drop"))
17053         action[0] = 3;
17054       else
17055         {
17056           clib_warning ("invalid action: '%s'", s);
17057           action[0] = 3;
17058         }
17059     }
17060   else
17061     return 0;
17062
17063   vec_free (s);
17064   return 1;
17065 }
17066
17067 /**
17068  * Add/del remote mapping to/from ONE control plane
17069  *
17070  * @param vam vpp API test context
17071  * @return return code
17072  */
17073 static int
17074 api_one_add_del_remote_mapping (vat_main_t * vam)
17075 {
17076   unformat_input_t *input = vam->input;
17077   vl_api_one_add_del_remote_mapping_t *mp;
17078   u32 vni = 0;
17079   lisp_eid_vat_t _eid, *eid = &_eid;
17080   lisp_eid_vat_t _seid, *seid = &_seid;
17081   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17082   u32 action = ~0, p, w, data_len;
17083   ip4_address_t rloc4;
17084   ip6_address_t rloc6;
17085   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17086   int ret;
17087
17088   memset (&rloc, 0, sizeof (rloc));
17089
17090   /* Parse args required to build the message */
17091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17092     {
17093       if (unformat (input, "del-all"))
17094         {
17095           del_all = 1;
17096         }
17097       else if (unformat (input, "del"))
17098         {
17099           is_add = 0;
17100         }
17101       else if (unformat (input, "add"))
17102         {
17103           is_add = 1;
17104         }
17105       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17106         {
17107           eid_set = 1;
17108         }
17109       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17110         {
17111           seid_set = 1;
17112         }
17113       else if (unformat (input, "vni %d", &vni))
17114         {
17115           ;
17116         }
17117       else if (unformat (input, "p %d w %d", &p, &w))
17118         {
17119           if (!curr_rloc)
17120             {
17121               errmsg ("No RLOC configured for setting priority/weight!");
17122               return -99;
17123             }
17124           curr_rloc->priority = p;
17125           curr_rloc->weight = w;
17126         }
17127       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17128         {
17129           rloc.is_ip4 = 1;
17130           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17131           vec_add1 (rlocs, rloc);
17132           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17133         }
17134       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17135         {
17136           rloc.is_ip4 = 0;
17137           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17138           vec_add1 (rlocs, rloc);
17139           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17140         }
17141       else if (unformat (input, "action %U",
17142                          unformat_negative_mapping_action, &action))
17143         {
17144           ;
17145         }
17146       else
17147         {
17148           clib_warning ("parse error '%U'", format_unformat_error, input);
17149           return -99;
17150         }
17151     }
17152
17153   if (0 == eid_set)
17154     {
17155       errmsg ("missing params!");
17156       return -99;
17157     }
17158
17159   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17160     {
17161       errmsg ("no action set for negative map-reply!");
17162       return -99;
17163     }
17164
17165   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17166
17167   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17168   mp->is_add = is_add;
17169   mp->vni = htonl (vni);
17170   mp->action = (u8) action;
17171   mp->is_src_dst = seid_set;
17172   mp->eid_len = eid->len;
17173   mp->seid_len = seid->len;
17174   mp->del_all = del_all;
17175   mp->eid_type = eid->type;
17176   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17177   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17178
17179   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17180   clib_memcpy (mp->rlocs, rlocs, data_len);
17181   vec_free (rlocs);
17182
17183   /* send it... */
17184   S (mp);
17185
17186   /* Wait for a reply... */
17187   W (ret);
17188   return ret;
17189 }
17190
17191 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17192
17193 /**
17194  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17195  * forwarding entries in data-plane accordingly.
17196  *
17197  * @param vam vpp API test context
17198  * @return return code
17199  */
17200 static int
17201 api_one_add_del_adjacency (vat_main_t * vam)
17202 {
17203   unformat_input_t *input = vam->input;
17204   vl_api_one_add_del_adjacency_t *mp;
17205   u32 vni = 0;
17206   ip4_address_t leid4, reid4;
17207   ip6_address_t leid6, reid6;
17208   u8 reid_mac[6] = { 0 };
17209   u8 leid_mac[6] = { 0 };
17210   u8 reid_type, leid_type;
17211   u32 leid_len = 0, reid_len = 0, len;
17212   u8 is_add = 1;
17213   int ret;
17214
17215   leid_type = reid_type = (u8) ~ 0;
17216
17217   /* Parse args required to build the message */
17218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17219     {
17220       if (unformat (input, "del"))
17221         {
17222           is_add = 0;
17223         }
17224       else if (unformat (input, "add"))
17225         {
17226           is_add = 1;
17227         }
17228       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17229                          &reid4, &len))
17230         {
17231           reid_type = 0;        /* ipv4 */
17232           reid_len = len;
17233         }
17234       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17235                          &reid6, &len))
17236         {
17237           reid_type = 1;        /* ipv6 */
17238           reid_len = len;
17239         }
17240       else if (unformat (input, "reid %U", unformat_ethernet_address,
17241                          reid_mac))
17242         {
17243           reid_type = 2;        /* mac */
17244         }
17245       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17246                          &leid4, &len))
17247         {
17248           leid_type = 0;        /* ipv4 */
17249           leid_len = len;
17250         }
17251       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17252                          &leid6, &len))
17253         {
17254           leid_type = 1;        /* ipv6 */
17255           leid_len = len;
17256         }
17257       else if (unformat (input, "leid %U", unformat_ethernet_address,
17258                          leid_mac))
17259         {
17260           leid_type = 2;        /* mac */
17261         }
17262       else if (unformat (input, "vni %d", &vni))
17263         {
17264           ;
17265         }
17266       else
17267         {
17268           errmsg ("parse error '%U'", format_unformat_error, input);
17269           return -99;
17270         }
17271     }
17272
17273   if ((u8) ~ 0 == reid_type)
17274     {
17275       errmsg ("missing params!");
17276       return -99;
17277     }
17278
17279   if (leid_type != reid_type)
17280     {
17281       errmsg ("remote and local EIDs are of different types!");
17282       return -99;
17283     }
17284
17285   M (ONE_ADD_DEL_ADJACENCY, mp);
17286   mp->is_add = is_add;
17287   mp->vni = htonl (vni);
17288   mp->leid_len = leid_len;
17289   mp->reid_len = reid_len;
17290   mp->eid_type = reid_type;
17291
17292   switch (mp->eid_type)
17293     {
17294     case 0:
17295       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17296       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17297       break;
17298     case 1:
17299       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17300       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17301       break;
17302     case 2:
17303       clib_memcpy (mp->leid, leid_mac, 6);
17304       clib_memcpy (mp->reid, reid_mac, 6);
17305       break;
17306     default:
17307       errmsg ("unknown EID type %d!", mp->eid_type);
17308       return 0;
17309     }
17310
17311   /* send it... */
17312   S (mp);
17313
17314   /* Wait for a reply... */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17320
17321 uword
17322 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17323 {
17324   u32 *mode = va_arg (*args, u32 *);
17325
17326   if (unformat (input, "lisp"))
17327     *mode = 0;
17328   else if (unformat (input, "vxlan"))
17329     *mode = 1;
17330   else
17331     return 0;
17332
17333   return 1;
17334 }
17335
17336 static int
17337 api_gpe_get_encap_mode (vat_main_t * vam)
17338 {
17339   vl_api_gpe_get_encap_mode_t *mp;
17340   int ret;
17341
17342   /* Construct the API message */
17343   M (GPE_GET_ENCAP_MODE, mp);
17344
17345   /* send it... */
17346   S (mp);
17347
17348   /* Wait for a reply... */
17349   W (ret);
17350   return ret;
17351 }
17352
17353 static int
17354 api_gpe_set_encap_mode (vat_main_t * vam)
17355 {
17356   unformat_input_t *input = vam->input;
17357   vl_api_gpe_set_encap_mode_t *mp;
17358   int ret;
17359   u32 mode = 0;
17360
17361   /* Parse args required to build the message */
17362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17363     {
17364       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17365         ;
17366       else
17367         break;
17368     }
17369
17370   /* Construct the API message */
17371   M (GPE_SET_ENCAP_MODE, mp);
17372
17373   mp->mode = mode;
17374
17375   /* send it... */
17376   S (mp);
17377
17378   /* Wait for a reply... */
17379   W (ret);
17380   return ret;
17381 }
17382
17383 static int
17384 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17385 {
17386   unformat_input_t *input = vam->input;
17387   vl_api_gpe_add_del_iface_t *mp;
17388   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17389   u32 dp_table = 0, vni = 0;
17390   int ret;
17391
17392   /* Parse args required to build the message */
17393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17394     {
17395       if (unformat (input, "up"))
17396         {
17397           action_set = 1;
17398           is_add = 1;
17399         }
17400       else if (unformat (input, "down"))
17401         {
17402           action_set = 1;
17403           is_add = 0;
17404         }
17405       else if (unformat (input, "table_id %d", &dp_table))
17406         {
17407           dp_table_set = 1;
17408         }
17409       else if (unformat (input, "bd_id %d", &dp_table))
17410         {
17411           dp_table_set = 1;
17412           is_l2 = 1;
17413         }
17414       else if (unformat (input, "vni %d", &vni))
17415         {
17416           vni_set = 1;
17417         }
17418       else
17419         break;
17420     }
17421
17422   if (action_set == 0)
17423     {
17424       errmsg ("Action not set");
17425       return -99;
17426     }
17427   if (dp_table_set == 0 || vni_set == 0)
17428     {
17429       errmsg ("vni and dp_table must be set");
17430       return -99;
17431     }
17432
17433   /* Construct the API message */
17434   M (GPE_ADD_DEL_IFACE, mp);
17435
17436   mp->is_add = is_add;
17437   mp->dp_table = clib_host_to_net_u32 (dp_table);
17438   mp->is_l2 = is_l2;
17439   mp->vni = clib_host_to_net_u32 (vni);
17440
17441   /* send it... */
17442   S (mp);
17443
17444   /* Wait for a reply... */
17445   W (ret);
17446   return ret;
17447 }
17448
17449 static int
17450 api_one_map_register_fallback_threshold (vat_main_t * vam)
17451 {
17452   unformat_input_t *input = vam->input;
17453   vl_api_one_map_register_fallback_threshold_t *mp;
17454   u32 value = 0;
17455   u8 is_set = 0;
17456   int ret;
17457
17458   /* Parse args required to build the message */
17459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17460     {
17461       if (unformat (input, "%u", &value))
17462         is_set = 1;
17463       else
17464         {
17465           clib_warning ("parse error '%U'", format_unformat_error, input);
17466           return -99;
17467         }
17468     }
17469
17470   if (!is_set)
17471     {
17472       errmsg ("fallback threshold value is missing!");
17473       return -99;
17474     }
17475
17476   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17477   mp->value = clib_host_to_net_u32 (value);
17478
17479   /* send it... */
17480   S (mp);
17481
17482   /* Wait for a reply... */
17483   W (ret);
17484   return ret;
17485 }
17486
17487 static int
17488 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17489 {
17490   vl_api_show_one_map_register_fallback_threshold_t *mp;
17491   int ret;
17492
17493   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17494
17495   /* send it... */
17496   S (mp);
17497
17498   /* Wait for a reply... */
17499   W (ret);
17500   return ret;
17501 }
17502
17503 uword
17504 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17505 {
17506   u32 *proto = va_arg (*args, u32 *);
17507
17508   if (unformat (input, "udp"))
17509     *proto = 1;
17510   else if (unformat (input, "api"))
17511     *proto = 2;
17512   else
17513     return 0;
17514
17515   return 1;
17516 }
17517
17518 static int
17519 api_one_set_transport_protocol (vat_main_t * vam)
17520 {
17521   unformat_input_t *input = vam->input;
17522   vl_api_one_set_transport_protocol_t *mp;
17523   u8 is_set = 0;
17524   u32 protocol = 0;
17525   int ret;
17526
17527   /* Parse args required to build the message */
17528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17529     {
17530       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17531         is_set = 1;
17532       else
17533         {
17534           clib_warning ("parse error '%U'", format_unformat_error, input);
17535           return -99;
17536         }
17537     }
17538
17539   if (!is_set)
17540     {
17541       errmsg ("Transport protocol missing!");
17542       return -99;
17543     }
17544
17545   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17546   mp->protocol = (u8) protocol;
17547
17548   /* send it... */
17549   S (mp);
17550
17551   /* Wait for a reply... */
17552   W (ret);
17553   return ret;
17554 }
17555
17556 static int
17557 api_one_get_transport_protocol (vat_main_t * vam)
17558 {
17559   vl_api_one_get_transport_protocol_t *mp;
17560   int ret;
17561
17562   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17563
17564   /* send it... */
17565   S (mp);
17566
17567   /* Wait for a reply... */
17568   W (ret);
17569   return ret;
17570 }
17571
17572 static int
17573 api_one_map_register_set_ttl (vat_main_t * vam)
17574 {
17575   unformat_input_t *input = vam->input;
17576   vl_api_one_map_register_set_ttl_t *mp;
17577   u32 ttl = 0;
17578   u8 is_set = 0;
17579   int ret;
17580
17581   /* Parse args required to build the message */
17582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17583     {
17584       if (unformat (input, "%u", &ttl))
17585         is_set = 1;
17586       else
17587         {
17588           clib_warning ("parse error '%U'", format_unformat_error, input);
17589           return -99;
17590         }
17591     }
17592
17593   if (!is_set)
17594     {
17595       errmsg ("TTL value missing!");
17596       return -99;
17597     }
17598
17599   M (ONE_MAP_REGISTER_SET_TTL, mp);
17600   mp->ttl = clib_host_to_net_u32 (ttl);
17601
17602   /* send it... */
17603   S (mp);
17604
17605   /* Wait for a reply... */
17606   W (ret);
17607   return ret;
17608 }
17609
17610 static int
17611 api_show_one_map_register_ttl (vat_main_t * vam)
17612 {
17613   vl_api_show_one_map_register_ttl_t *mp;
17614   int ret;
17615
17616   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17617
17618   /* send it... */
17619   S (mp);
17620
17621   /* Wait for a reply... */
17622   W (ret);
17623   return ret;
17624 }
17625
17626 /**
17627  * Add/del map request itr rlocs from ONE control plane and updates
17628  *
17629  * @param vam vpp API test context
17630  * @return return code
17631  */
17632 static int
17633 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17634 {
17635   unformat_input_t *input = vam->input;
17636   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17637   u8 *locator_set_name = 0;
17638   u8 locator_set_name_set = 0;
17639   u8 is_add = 1;
17640   int ret;
17641
17642   /* Parse args required to build the message */
17643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17644     {
17645       if (unformat (input, "del"))
17646         {
17647           is_add = 0;
17648         }
17649       else if (unformat (input, "%_%v%_", &locator_set_name))
17650         {
17651           locator_set_name_set = 1;
17652         }
17653       else
17654         {
17655           clib_warning ("parse error '%U'", format_unformat_error, input);
17656           return -99;
17657         }
17658     }
17659
17660   if (is_add && !locator_set_name_set)
17661     {
17662       errmsg ("itr-rloc is not set!");
17663       return -99;
17664     }
17665
17666   if (is_add && vec_len (locator_set_name) > 64)
17667     {
17668       errmsg ("itr-rloc locator-set name too long");
17669       vec_free (locator_set_name);
17670       return -99;
17671     }
17672
17673   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17674   mp->is_add = is_add;
17675   if (is_add)
17676     {
17677       clib_memcpy (mp->locator_set_name, locator_set_name,
17678                    vec_len (locator_set_name));
17679     }
17680   else
17681     {
17682       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17683     }
17684   vec_free (locator_set_name);
17685
17686   /* send it... */
17687   S (mp);
17688
17689   /* Wait for a reply... */
17690   W (ret);
17691   return ret;
17692 }
17693
17694 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17695
17696 static int
17697 api_one_locator_dump (vat_main_t * vam)
17698 {
17699   unformat_input_t *input = vam->input;
17700   vl_api_one_locator_dump_t *mp;
17701   vl_api_control_ping_t *mp_ping;
17702   u8 is_index_set = 0, is_name_set = 0;
17703   u8 *ls_name = 0;
17704   u32 ls_index = ~0;
17705   int ret;
17706
17707   /* Parse args required to build the message */
17708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17709     {
17710       if (unformat (input, "ls_name %_%v%_", &ls_name))
17711         {
17712           is_name_set = 1;
17713         }
17714       else if (unformat (input, "ls_index %d", &ls_index))
17715         {
17716           is_index_set = 1;
17717         }
17718       else
17719         {
17720           errmsg ("parse error '%U'", format_unformat_error, input);
17721           return -99;
17722         }
17723     }
17724
17725   if (!is_index_set && !is_name_set)
17726     {
17727       errmsg ("error: expected one of index or name!");
17728       return -99;
17729     }
17730
17731   if (is_index_set && is_name_set)
17732     {
17733       errmsg ("error: only one param expected!");
17734       return -99;
17735     }
17736
17737   if (vec_len (ls_name) > 62)
17738     {
17739       errmsg ("error: locator set name too long!");
17740       return -99;
17741     }
17742
17743   if (!vam->json_output)
17744     {
17745       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17746     }
17747
17748   M (ONE_LOCATOR_DUMP, mp);
17749   mp->is_index_set = is_index_set;
17750
17751   if (is_index_set)
17752     mp->ls_index = clib_host_to_net_u32 (ls_index);
17753   else
17754     {
17755       vec_add1 (ls_name, 0);
17756       strncpy ((char *) mp->ls_name, (char *) ls_name,
17757                sizeof (mp->ls_name) - 1);
17758     }
17759
17760   /* send it... */
17761   S (mp);
17762
17763   /* Use a control ping for synchronization */
17764   MPING (CONTROL_PING, mp_ping);
17765   S (mp_ping);
17766
17767   /* Wait for a reply... */
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define api_lisp_locator_dump api_one_locator_dump
17773
17774 static int
17775 api_one_locator_set_dump (vat_main_t * vam)
17776 {
17777   vl_api_one_locator_set_dump_t *mp;
17778   vl_api_control_ping_t *mp_ping;
17779   unformat_input_t *input = vam->input;
17780   u8 filter = 0;
17781   int ret;
17782
17783   /* Parse args required to build the message */
17784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17785     {
17786       if (unformat (input, "local"))
17787         {
17788           filter = 1;
17789         }
17790       else if (unformat (input, "remote"))
17791         {
17792           filter = 2;
17793         }
17794       else
17795         {
17796           errmsg ("parse error '%U'", format_unformat_error, input);
17797           return -99;
17798         }
17799     }
17800
17801   if (!vam->json_output)
17802     {
17803       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17804     }
17805
17806   M (ONE_LOCATOR_SET_DUMP, mp);
17807
17808   mp->filter = filter;
17809
17810   /* send it... */
17811   S (mp);
17812
17813   /* Use a control ping for synchronization */
17814   MPING (CONTROL_PING, mp_ping);
17815   S (mp_ping);
17816
17817   /* Wait for a reply... */
17818   W (ret);
17819   return ret;
17820 }
17821
17822 #define api_lisp_locator_set_dump api_one_locator_set_dump
17823
17824 static int
17825 api_one_eid_table_map_dump (vat_main_t * vam)
17826 {
17827   u8 is_l2 = 0;
17828   u8 mode_set = 0;
17829   unformat_input_t *input = vam->input;
17830   vl_api_one_eid_table_map_dump_t *mp;
17831   vl_api_control_ping_t *mp_ping;
17832   int ret;
17833
17834   /* Parse args required to build the message */
17835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17836     {
17837       if (unformat (input, "l2"))
17838         {
17839           is_l2 = 1;
17840           mode_set = 1;
17841         }
17842       else if (unformat (input, "l3"))
17843         {
17844           is_l2 = 0;
17845           mode_set = 1;
17846         }
17847       else
17848         {
17849           errmsg ("parse error '%U'", format_unformat_error, input);
17850           return -99;
17851         }
17852     }
17853
17854   if (!mode_set)
17855     {
17856       errmsg ("expected one of 'l2' or 'l3' parameter!");
17857       return -99;
17858     }
17859
17860   if (!vam->json_output)
17861     {
17862       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17863     }
17864
17865   M (ONE_EID_TABLE_MAP_DUMP, mp);
17866   mp->is_l2 = is_l2;
17867
17868   /* send it... */
17869   S (mp);
17870
17871   /* Use a control ping for synchronization */
17872   MPING (CONTROL_PING, mp_ping);
17873   S (mp_ping);
17874
17875   /* Wait for a reply... */
17876   W (ret);
17877   return ret;
17878 }
17879
17880 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17881
17882 static int
17883 api_one_eid_table_vni_dump (vat_main_t * vam)
17884 {
17885   vl_api_one_eid_table_vni_dump_t *mp;
17886   vl_api_control_ping_t *mp_ping;
17887   int ret;
17888
17889   if (!vam->json_output)
17890     {
17891       print (vam->ofp, "VNI");
17892     }
17893
17894   M (ONE_EID_TABLE_VNI_DUMP, mp);
17895
17896   /* send it... */
17897   S (mp);
17898
17899   /* Use a control ping for synchronization */
17900   MPING (CONTROL_PING, mp_ping);
17901   S (mp_ping);
17902
17903   /* Wait for a reply... */
17904   W (ret);
17905   return ret;
17906 }
17907
17908 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17909
17910 static int
17911 api_one_eid_table_dump (vat_main_t * vam)
17912 {
17913   unformat_input_t *i = vam->input;
17914   vl_api_one_eid_table_dump_t *mp;
17915   vl_api_control_ping_t *mp_ping;
17916   struct in_addr ip4;
17917   struct in6_addr ip6;
17918   u8 mac[6];
17919   u8 eid_type = ~0, eid_set = 0;
17920   u32 prefix_length = ~0, t, vni = 0;
17921   u8 filter = 0;
17922   int ret;
17923   lisp_nsh_api_t nsh;
17924
17925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17926     {
17927       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17928         {
17929           eid_set = 1;
17930           eid_type = 0;
17931           prefix_length = t;
17932         }
17933       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17934         {
17935           eid_set = 1;
17936           eid_type = 1;
17937           prefix_length = t;
17938         }
17939       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17940         {
17941           eid_set = 1;
17942           eid_type = 2;
17943         }
17944       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17945         {
17946           eid_set = 1;
17947           eid_type = 3;
17948         }
17949       else if (unformat (i, "vni %d", &t))
17950         {
17951           vni = t;
17952         }
17953       else if (unformat (i, "local"))
17954         {
17955           filter = 1;
17956         }
17957       else if (unformat (i, "remote"))
17958         {
17959           filter = 2;
17960         }
17961       else
17962         {
17963           errmsg ("parse error '%U'", format_unformat_error, i);
17964           return -99;
17965         }
17966     }
17967
17968   if (!vam->json_output)
17969     {
17970       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17971              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17972     }
17973
17974   M (ONE_EID_TABLE_DUMP, mp);
17975
17976   mp->filter = filter;
17977   if (eid_set)
17978     {
17979       mp->eid_set = 1;
17980       mp->vni = htonl (vni);
17981       mp->eid_type = eid_type;
17982       switch (eid_type)
17983         {
17984         case 0:
17985           mp->prefix_length = prefix_length;
17986           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17987           break;
17988         case 1:
17989           mp->prefix_length = prefix_length;
17990           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17991           break;
17992         case 2:
17993           clib_memcpy (mp->eid, mac, sizeof (mac));
17994           break;
17995         case 3:
17996           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17997           break;
17998         default:
17999           errmsg ("unknown EID type %d!", eid_type);
18000           return -99;
18001         }
18002     }
18003
18004   /* send it... */
18005   S (mp);
18006
18007   /* Use a control ping for synchronization */
18008   MPING (CONTROL_PING, mp_ping);
18009   S (mp_ping);
18010
18011   /* Wait for a reply... */
18012   W (ret);
18013   return ret;
18014 }
18015
18016 #define api_lisp_eid_table_dump api_one_eid_table_dump
18017
18018 static int
18019 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18020 {
18021   unformat_input_t *i = vam->input;
18022   vl_api_gpe_fwd_entries_get_t *mp;
18023   u8 vni_set = 0;
18024   u32 vni = ~0;
18025   int ret;
18026
18027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18028     {
18029       if (unformat (i, "vni %d", &vni))
18030         {
18031           vni_set = 1;
18032         }
18033       else
18034         {
18035           errmsg ("parse error '%U'", format_unformat_error, i);
18036           return -99;
18037         }
18038     }
18039
18040   if (!vni_set)
18041     {
18042       errmsg ("vni not set!");
18043       return -99;
18044     }
18045
18046   if (!vam->json_output)
18047     {
18048       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18049              "leid", "reid");
18050     }
18051
18052   M (GPE_FWD_ENTRIES_GET, mp);
18053   mp->vni = clib_host_to_net_u32 (vni);
18054
18055   /* send it... */
18056   S (mp);
18057
18058   /* Wait for a reply... */
18059   W (ret);
18060   return ret;
18061 }
18062
18063 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18064 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18065 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18066 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18067 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18068 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18069 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18070 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18071
18072 static int
18073 api_one_adjacencies_get (vat_main_t * vam)
18074 {
18075   unformat_input_t *i = vam->input;
18076   vl_api_one_adjacencies_get_t *mp;
18077   u8 vni_set = 0;
18078   u32 vni = ~0;
18079   int ret;
18080
18081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18082     {
18083       if (unformat (i, "vni %d", &vni))
18084         {
18085           vni_set = 1;
18086         }
18087       else
18088         {
18089           errmsg ("parse error '%U'", format_unformat_error, i);
18090           return -99;
18091         }
18092     }
18093
18094   if (!vni_set)
18095     {
18096       errmsg ("vni not set!");
18097       return -99;
18098     }
18099
18100   if (!vam->json_output)
18101     {
18102       print (vam->ofp, "%s %40s", "leid", "reid");
18103     }
18104
18105   M (ONE_ADJACENCIES_GET, mp);
18106   mp->vni = clib_host_to_net_u32 (vni);
18107
18108   /* send it... */
18109   S (mp);
18110
18111   /* Wait for a reply... */
18112   W (ret);
18113   return ret;
18114 }
18115
18116 #define api_lisp_adjacencies_get api_one_adjacencies_get
18117
18118 static int
18119 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18120 {
18121   unformat_input_t *i = vam->input;
18122   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18123   int ret;
18124   u8 ip_family_set = 0, is_ip4 = 1;
18125
18126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18127     {
18128       if (unformat (i, "ip4"))
18129         {
18130           ip_family_set = 1;
18131           is_ip4 = 1;
18132         }
18133       else if (unformat (i, "ip6"))
18134         {
18135           ip_family_set = 1;
18136           is_ip4 = 0;
18137         }
18138       else
18139         {
18140           errmsg ("parse error '%U'", format_unformat_error, i);
18141           return -99;
18142         }
18143     }
18144
18145   if (!ip_family_set)
18146     {
18147       errmsg ("ip family not set!");
18148       return -99;
18149     }
18150
18151   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18152   mp->is_ip4 = is_ip4;
18153
18154   /* send it... */
18155   S (mp);
18156
18157   /* Wait for a reply... */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 static int
18163 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18164 {
18165   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18166   int ret;
18167
18168   if (!vam->json_output)
18169     {
18170       print (vam->ofp, "VNIs");
18171     }
18172
18173   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18174
18175   /* send it... */
18176   S (mp);
18177
18178   /* Wait for a reply... */
18179   W (ret);
18180   return ret;
18181 }
18182
18183 static int
18184 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18185 {
18186   unformat_input_t *i = vam->input;
18187   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18188   int ret = 0;
18189   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18190   struct in_addr ip4;
18191   struct in6_addr ip6;
18192   u32 table_id = 0, nh_sw_if_index = ~0;
18193
18194   memset (&ip4, 0, sizeof (ip4));
18195   memset (&ip6, 0, sizeof (ip6));
18196
18197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18198     {
18199       if (unformat (i, "del"))
18200         is_add = 0;
18201       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18202                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18203         {
18204           ip_set = 1;
18205           is_ip4 = 1;
18206         }
18207       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18208                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18209         {
18210           ip_set = 1;
18211           is_ip4 = 0;
18212         }
18213       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18214         {
18215           ip_set = 1;
18216           is_ip4 = 1;
18217           nh_sw_if_index = ~0;
18218         }
18219       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18220         {
18221           ip_set = 1;
18222           is_ip4 = 0;
18223           nh_sw_if_index = ~0;
18224         }
18225       else if (unformat (i, "table %d", &table_id))
18226         ;
18227       else
18228         {
18229           errmsg ("parse error '%U'", format_unformat_error, i);
18230           return -99;
18231         }
18232     }
18233
18234   if (!ip_set)
18235     {
18236       errmsg ("nh addr not set!");
18237       return -99;
18238     }
18239
18240   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18241   mp->is_add = is_add;
18242   mp->table_id = clib_host_to_net_u32 (table_id);
18243   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18244   mp->is_ip4 = is_ip4;
18245   if (is_ip4)
18246     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18247   else
18248     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18249
18250   /* send it... */
18251   S (mp);
18252
18253   /* Wait for a reply... */
18254   W (ret);
18255   return ret;
18256 }
18257
18258 static int
18259 api_one_map_server_dump (vat_main_t * vam)
18260 {
18261   vl_api_one_map_server_dump_t *mp;
18262   vl_api_control_ping_t *mp_ping;
18263   int ret;
18264
18265   if (!vam->json_output)
18266     {
18267       print (vam->ofp, "%=20s", "Map server");
18268     }
18269
18270   M (ONE_MAP_SERVER_DUMP, mp);
18271   /* send it... */
18272   S (mp);
18273
18274   /* Use a control ping for synchronization */
18275   MPING (CONTROL_PING, mp_ping);
18276   S (mp_ping);
18277
18278   /* Wait for a reply... */
18279   W (ret);
18280   return ret;
18281 }
18282
18283 #define api_lisp_map_server_dump api_one_map_server_dump
18284
18285 static int
18286 api_one_map_resolver_dump (vat_main_t * vam)
18287 {
18288   vl_api_one_map_resolver_dump_t *mp;
18289   vl_api_control_ping_t *mp_ping;
18290   int ret;
18291
18292   if (!vam->json_output)
18293     {
18294       print (vam->ofp, "%=20s", "Map resolver");
18295     }
18296
18297   M (ONE_MAP_RESOLVER_DUMP, mp);
18298   /* send it... */
18299   S (mp);
18300
18301   /* Use a control ping for synchronization */
18302   MPING (CONTROL_PING, mp_ping);
18303   S (mp_ping);
18304
18305   /* Wait for a reply... */
18306   W (ret);
18307   return ret;
18308 }
18309
18310 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18311
18312 static int
18313 api_one_stats_flush (vat_main_t * vam)
18314 {
18315   vl_api_one_stats_flush_t *mp;
18316   int ret = 0;
18317
18318   M (ONE_STATS_FLUSH, mp);
18319   S (mp);
18320   W (ret);
18321   return ret;
18322 }
18323
18324 static int
18325 api_one_stats_dump (vat_main_t * vam)
18326 {
18327   vl_api_one_stats_dump_t *mp;
18328   vl_api_control_ping_t *mp_ping;
18329   int ret;
18330
18331   M (ONE_STATS_DUMP, mp);
18332   /* send it... */
18333   S (mp);
18334
18335   /* Use a control ping for synchronization */
18336   MPING (CONTROL_PING, mp_ping);
18337   S (mp_ping);
18338
18339   /* Wait for a reply... */
18340   W (ret);
18341   return ret;
18342 }
18343
18344 static int
18345 api_show_one_status (vat_main_t * vam)
18346 {
18347   vl_api_show_one_status_t *mp;
18348   int ret;
18349
18350   if (!vam->json_output)
18351     {
18352       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18353     }
18354
18355   M (SHOW_ONE_STATUS, mp);
18356   /* send it... */
18357   S (mp);
18358   /* Wait for a reply... */
18359   W (ret);
18360   return ret;
18361 }
18362
18363 #define api_show_lisp_status api_show_one_status
18364
18365 static int
18366 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18367 {
18368   vl_api_gpe_fwd_entry_path_dump_t *mp;
18369   vl_api_control_ping_t *mp_ping;
18370   unformat_input_t *i = vam->input;
18371   u32 fwd_entry_index = ~0;
18372   int ret;
18373
18374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18375     {
18376       if (unformat (i, "index %d", &fwd_entry_index))
18377         ;
18378       else
18379         break;
18380     }
18381
18382   if (~0 == fwd_entry_index)
18383     {
18384       errmsg ("no index specified!");
18385       return -99;
18386     }
18387
18388   if (!vam->json_output)
18389     {
18390       print (vam->ofp, "first line");
18391     }
18392
18393   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18394
18395   /* send it... */
18396   S (mp);
18397   /* Use a control ping for synchronization */
18398   MPING (CONTROL_PING, mp_ping);
18399   S (mp_ping);
18400
18401   /* Wait for a reply... */
18402   W (ret);
18403   return ret;
18404 }
18405
18406 static int
18407 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18408 {
18409   vl_api_one_get_map_request_itr_rlocs_t *mp;
18410   int ret;
18411
18412   if (!vam->json_output)
18413     {
18414       print (vam->ofp, "%=20s", "itr-rlocs:");
18415     }
18416
18417   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18418   /* send it... */
18419   S (mp);
18420   /* Wait for a reply... */
18421   W (ret);
18422   return ret;
18423 }
18424
18425 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18426
18427 static int
18428 api_af_packet_create (vat_main_t * vam)
18429 {
18430   unformat_input_t *i = vam->input;
18431   vl_api_af_packet_create_t *mp;
18432   u8 *host_if_name = 0;
18433   u8 hw_addr[6];
18434   u8 random_hw_addr = 1;
18435   int ret;
18436
18437   memset (hw_addr, 0, sizeof (hw_addr));
18438
18439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18440     {
18441       if (unformat (i, "name %s", &host_if_name))
18442         vec_add1 (host_if_name, 0);
18443       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18444         random_hw_addr = 0;
18445       else
18446         break;
18447     }
18448
18449   if (!vec_len (host_if_name))
18450     {
18451       errmsg ("host-interface name must be specified");
18452       return -99;
18453     }
18454
18455   if (vec_len (host_if_name) > 64)
18456     {
18457       errmsg ("host-interface name too long");
18458       return -99;
18459     }
18460
18461   M (AF_PACKET_CREATE, mp);
18462
18463   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18464   clib_memcpy (mp->hw_addr, hw_addr, 6);
18465   mp->use_random_hw_addr = random_hw_addr;
18466   vec_free (host_if_name);
18467
18468   S (mp);
18469
18470   /* *INDENT-OFF* */
18471   W2 (ret,
18472       ({
18473         if (ret == 0)
18474           fprintf (vam->ofp ? vam->ofp : stderr,
18475                    " new sw_if_index = %d\n", vam->sw_if_index);
18476       }));
18477   /* *INDENT-ON* */
18478   return ret;
18479 }
18480
18481 static int
18482 api_af_packet_delete (vat_main_t * vam)
18483 {
18484   unformat_input_t *i = vam->input;
18485   vl_api_af_packet_delete_t *mp;
18486   u8 *host_if_name = 0;
18487   int ret;
18488
18489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18490     {
18491       if (unformat (i, "name %s", &host_if_name))
18492         vec_add1 (host_if_name, 0);
18493       else
18494         break;
18495     }
18496
18497   if (!vec_len (host_if_name))
18498     {
18499       errmsg ("host-interface name must be specified");
18500       return -99;
18501     }
18502
18503   if (vec_len (host_if_name) > 64)
18504     {
18505       errmsg ("host-interface name too long");
18506       return -99;
18507     }
18508
18509   M (AF_PACKET_DELETE, mp);
18510
18511   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18512   vec_free (host_if_name);
18513
18514   S (mp);
18515   W (ret);
18516   return ret;
18517 }
18518
18519 static int
18520 api_policer_add_del (vat_main_t * vam)
18521 {
18522   unformat_input_t *i = vam->input;
18523   vl_api_policer_add_del_t *mp;
18524   u8 is_add = 1;
18525   u8 *name = 0;
18526   u32 cir = 0;
18527   u32 eir = 0;
18528   u64 cb = 0;
18529   u64 eb = 0;
18530   u8 rate_type = 0;
18531   u8 round_type = 0;
18532   u8 type = 0;
18533   u8 color_aware = 0;
18534   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18535   int ret;
18536
18537   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18538   conform_action.dscp = 0;
18539   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18540   exceed_action.dscp = 0;
18541   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18542   violate_action.dscp = 0;
18543
18544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18545     {
18546       if (unformat (i, "del"))
18547         is_add = 0;
18548       else if (unformat (i, "name %s", &name))
18549         vec_add1 (name, 0);
18550       else if (unformat (i, "cir %u", &cir))
18551         ;
18552       else if (unformat (i, "eir %u", &eir))
18553         ;
18554       else if (unformat (i, "cb %u", &cb))
18555         ;
18556       else if (unformat (i, "eb %u", &eb))
18557         ;
18558       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18559                          &rate_type))
18560         ;
18561       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18562                          &round_type))
18563         ;
18564       else if (unformat (i, "type %U", unformat_policer_type, &type))
18565         ;
18566       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18567                          &conform_action))
18568         ;
18569       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18570                          &exceed_action))
18571         ;
18572       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18573                          &violate_action))
18574         ;
18575       else if (unformat (i, "color-aware"))
18576         color_aware = 1;
18577       else
18578         break;
18579     }
18580
18581   if (!vec_len (name))
18582     {
18583       errmsg ("policer name must be specified");
18584       return -99;
18585     }
18586
18587   if (vec_len (name) > 64)
18588     {
18589       errmsg ("policer name too long");
18590       return -99;
18591     }
18592
18593   M (POLICER_ADD_DEL, mp);
18594
18595   clib_memcpy (mp->name, name, vec_len (name));
18596   vec_free (name);
18597   mp->is_add = is_add;
18598   mp->cir = ntohl (cir);
18599   mp->eir = ntohl (eir);
18600   mp->cb = clib_net_to_host_u64 (cb);
18601   mp->eb = clib_net_to_host_u64 (eb);
18602   mp->rate_type = rate_type;
18603   mp->round_type = round_type;
18604   mp->type = type;
18605   mp->conform_action_type = conform_action.action_type;
18606   mp->conform_dscp = conform_action.dscp;
18607   mp->exceed_action_type = exceed_action.action_type;
18608   mp->exceed_dscp = exceed_action.dscp;
18609   mp->violate_action_type = violate_action.action_type;
18610   mp->violate_dscp = violate_action.dscp;
18611   mp->color_aware = color_aware;
18612
18613   S (mp);
18614   W (ret);
18615   return ret;
18616 }
18617
18618 static int
18619 api_policer_dump (vat_main_t * vam)
18620 {
18621   unformat_input_t *i = vam->input;
18622   vl_api_policer_dump_t *mp;
18623   vl_api_control_ping_t *mp_ping;
18624   u8 *match_name = 0;
18625   u8 match_name_valid = 0;
18626   int ret;
18627
18628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18629     {
18630       if (unformat (i, "name %s", &match_name))
18631         {
18632           vec_add1 (match_name, 0);
18633           match_name_valid = 1;
18634         }
18635       else
18636         break;
18637     }
18638
18639   M (POLICER_DUMP, mp);
18640   mp->match_name_valid = match_name_valid;
18641   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18642   vec_free (match_name);
18643   /* send it... */
18644   S (mp);
18645
18646   /* Use a control ping for synchronization */
18647   MPING (CONTROL_PING, mp_ping);
18648   S (mp_ping);
18649
18650   /* Wait for a reply... */
18651   W (ret);
18652   return ret;
18653 }
18654
18655 static int
18656 api_policer_classify_set_interface (vat_main_t * vam)
18657 {
18658   unformat_input_t *i = vam->input;
18659   vl_api_policer_classify_set_interface_t *mp;
18660   u32 sw_if_index;
18661   int sw_if_index_set;
18662   u32 ip4_table_index = ~0;
18663   u32 ip6_table_index = ~0;
18664   u32 l2_table_index = ~0;
18665   u8 is_add = 1;
18666   int ret;
18667
18668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18669     {
18670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18671         sw_if_index_set = 1;
18672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18673         sw_if_index_set = 1;
18674       else if (unformat (i, "del"))
18675         is_add = 0;
18676       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18677         ;
18678       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18679         ;
18680       else if (unformat (i, "l2-table %d", &l2_table_index))
18681         ;
18682       else
18683         {
18684           clib_warning ("parse error '%U'", format_unformat_error, i);
18685           return -99;
18686         }
18687     }
18688
18689   if (sw_if_index_set == 0)
18690     {
18691       errmsg ("missing interface name or sw_if_index");
18692       return -99;
18693     }
18694
18695   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18696
18697   mp->sw_if_index = ntohl (sw_if_index);
18698   mp->ip4_table_index = ntohl (ip4_table_index);
18699   mp->ip6_table_index = ntohl (ip6_table_index);
18700   mp->l2_table_index = ntohl (l2_table_index);
18701   mp->is_add = is_add;
18702
18703   S (mp);
18704   W (ret);
18705   return ret;
18706 }
18707
18708 static int
18709 api_policer_classify_dump (vat_main_t * vam)
18710 {
18711   unformat_input_t *i = vam->input;
18712   vl_api_policer_classify_dump_t *mp;
18713   vl_api_control_ping_t *mp_ping;
18714   u8 type = POLICER_CLASSIFY_N_TABLES;
18715   int ret;
18716
18717   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18718     ;
18719   else
18720     {
18721       errmsg ("classify table type must be specified");
18722       return -99;
18723     }
18724
18725   if (!vam->json_output)
18726     {
18727       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18728     }
18729
18730   M (POLICER_CLASSIFY_DUMP, mp);
18731   mp->type = type;
18732   /* send it... */
18733   S (mp);
18734
18735   /* Use a control ping for synchronization */
18736   MPING (CONTROL_PING, mp_ping);
18737   S (mp_ping);
18738
18739   /* Wait for a reply... */
18740   W (ret);
18741   return ret;
18742 }
18743
18744 static int
18745 api_netmap_create (vat_main_t * vam)
18746 {
18747   unformat_input_t *i = vam->input;
18748   vl_api_netmap_create_t *mp;
18749   u8 *if_name = 0;
18750   u8 hw_addr[6];
18751   u8 random_hw_addr = 1;
18752   u8 is_pipe = 0;
18753   u8 is_master = 0;
18754   int ret;
18755
18756   memset (hw_addr, 0, sizeof (hw_addr));
18757
18758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18759     {
18760       if (unformat (i, "name %s", &if_name))
18761         vec_add1 (if_name, 0);
18762       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18763         random_hw_addr = 0;
18764       else if (unformat (i, "pipe"))
18765         is_pipe = 1;
18766       else if (unformat (i, "master"))
18767         is_master = 1;
18768       else if (unformat (i, "slave"))
18769         is_master = 0;
18770       else
18771         break;
18772     }
18773
18774   if (!vec_len (if_name))
18775     {
18776       errmsg ("interface name must be specified");
18777       return -99;
18778     }
18779
18780   if (vec_len (if_name) > 64)
18781     {
18782       errmsg ("interface name too long");
18783       return -99;
18784     }
18785
18786   M (NETMAP_CREATE, mp);
18787
18788   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18789   clib_memcpy (mp->hw_addr, hw_addr, 6);
18790   mp->use_random_hw_addr = random_hw_addr;
18791   mp->is_pipe = is_pipe;
18792   mp->is_master = is_master;
18793   vec_free (if_name);
18794
18795   S (mp);
18796   W (ret);
18797   return ret;
18798 }
18799
18800 static int
18801 api_netmap_delete (vat_main_t * vam)
18802 {
18803   unformat_input_t *i = vam->input;
18804   vl_api_netmap_delete_t *mp;
18805   u8 *if_name = 0;
18806   int ret;
18807
18808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18809     {
18810       if (unformat (i, "name %s", &if_name))
18811         vec_add1 (if_name, 0);
18812       else
18813         break;
18814     }
18815
18816   if (!vec_len (if_name))
18817     {
18818       errmsg ("interface name must be specified");
18819       return -99;
18820     }
18821
18822   if (vec_len (if_name) > 64)
18823     {
18824       errmsg ("interface name too long");
18825       return -99;
18826     }
18827
18828   M (NETMAP_DELETE, mp);
18829
18830   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18831   vec_free (if_name);
18832
18833   S (mp);
18834   W (ret);
18835   return ret;
18836 }
18837
18838 static void
18839 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18840 {
18841   if (fp->afi == IP46_TYPE_IP6)
18842     print (vam->ofp,
18843            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18844            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18845            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18846            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18847            format_ip6_address, fp->next_hop);
18848   else if (fp->afi == IP46_TYPE_IP4)
18849     print (vam->ofp,
18850            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18851            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18852            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18853            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18854            format_ip4_address, fp->next_hop);
18855 }
18856
18857 static void
18858 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18859                                  vl_api_fib_path2_t * fp)
18860 {
18861   struct in_addr ip4;
18862   struct in6_addr ip6;
18863
18864   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18865   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18866   vat_json_object_add_uint (node, "is_local", fp->is_local);
18867   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18868   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18869   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18870   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18871   if (fp->afi == IP46_TYPE_IP4)
18872     {
18873       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18874       vat_json_object_add_ip4 (node, "next_hop", ip4);
18875     }
18876   else if (fp->afi == IP46_TYPE_IP6)
18877     {
18878       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18879       vat_json_object_add_ip6 (node, "next_hop", ip6);
18880     }
18881 }
18882
18883 static void
18884 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18885 {
18886   vat_main_t *vam = &vat_main;
18887   int count = ntohl (mp->mt_count);
18888   vl_api_fib_path2_t *fp;
18889   i32 i;
18890
18891   print (vam->ofp, "[%d]: sw_if_index %d via:",
18892          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18893   fp = mp->mt_paths;
18894   for (i = 0; i < count; i++)
18895     {
18896       vl_api_mpls_fib_path_print (vam, fp);
18897       fp++;
18898     }
18899
18900   print (vam->ofp, "");
18901 }
18902
18903 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18904 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18905
18906 static void
18907 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18908 {
18909   vat_main_t *vam = &vat_main;
18910   vat_json_node_t *node = NULL;
18911   int count = ntohl (mp->mt_count);
18912   vl_api_fib_path2_t *fp;
18913   i32 i;
18914
18915   if (VAT_JSON_ARRAY != vam->json_tree.type)
18916     {
18917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18918       vat_json_init_array (&vam->json_tree);
18919     }
18920   node = vat_json_array_add (&vam->json_tree);
18921
18922   vat_json_init_object (node);
18923   vat_json_object_add_uint (node, "tunnel_index",
18924                             ntohl (mp->mt_tunnel_index));
18925   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18926
18927   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18928
18929   fp = mp->mt_paths;
18930   for (i = 0; i < count; i++)
18931     {
18932       vl_api_mpls_fib_path_json_print (node, fp);
18933       fp++;
18934     }
18935 }
18936
18937 static int
18938 api_mpls_tunnel_dump (vat_main_t * vam)
18939 {
18940   vl_api_mpls_tunnel_dump_t *mp;
18941   vl_api_control_ping_t *mp_ping;
18942   i32 index = -1;
18943   int ret;
18944
18945   /* Parse args required to build the message */
18946   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18947     {
18948       if (!unformat (vam->input, "tunnel_index %d", &index))
18949         {
18950           index = -1;
18951           break;
18952         }
18953     }
18954
18955   print (vam->ofp, "  tunnel_index %d", index);
18956
18957   M (MPLS_TUNNEL_DUMP, mp);
18958   mp->tunnel_index = htonl (index);
18959   S (mp);
18960
18961   /* Use a control ping for synchronization */
18962   MPING (CONTROL_PING, mp_ping);
18963   S (mp_ping);
18964
18965   W (ret);
18966   return ret;
18967 }
18968
18969 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18970 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18971
18972
18973 static void
18974 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18975 {
18976   vat_main_t *vam = &vat_main;
18977   int count = ntohl (mp->count);
18978   vl_api_fib_path2_t *fp;
18979   int i;
18980
18981   print (vam->ofp,
18982          "table-id %d, label %u, ess_bit %u",
18983          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18984   fp = mp->path;
18985   for (i = 0; i < count; i++)
18986     {
18987       vl_api_mpls_fib_path_print (vam, fp);
18988       fp++;
18989     }
18990 }
18991
18992 static void vl_api_mpls_fib_details_t_handler_json
18993   (vl_api_mpls_fib_details_t * mp)
18994 {
18995   vat_main_t *vam = &vat_main;
18996   int count = ntohl (mp->count);
18997   vat_json_node_t *node = NULL;
18998   vl_api_fib_path2_t *fp;
18999   int i;
19000
19001   if (VAT_JSON_ARRAY != vam->json_tree.type)
19002     {
19003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19004       vat_json_init_array (&vam->json_tree);
19005     }
19006   node = vat_json_array_add (&vam->json_tree);
19007
19008   vat_json_init_object (node);
19009   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19010   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19011   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19012   vat_json_object_add_uint (node, "path_count", count);
19013   fp = mp->path;
19014   for (i = 0; i < count; i++)
19015     {
19016       vl_api_mpls_fib_path_json_print (node, fp);
19017       fp++;
19018     }
19019 }
19020
19021 static int
19022 api_mpls_fib_dump (vat_main_t * vam)
19023 {
19024   vl_api_mpls_fib_dump_t *mp;
19025   vl_api_control_ping_t *mp_ping;
19026   int ret;
19027
19028   M (MPLS_FIB_DUMP, mp);
19029   S (mp);
19030
19031   /* Use a control ping for synchronization */
19032   MPING (CONTROL_PING, mp_ping);
19033   S (mp_ping);
19034
19035   W (ret);
19036   return ret;
19037 }
19038
19039 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19040 #define vl_api_ip_fib_details_t_print vl_noop_handler
19041
19042 static void
19043 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19044 {
19045   vat_main_t *vam = &vat_main;
19046   int count = ntohl (mp->count);
19047   vl_api_fib_path_t *fp;
19048   int i;
19049
19050   print (vam->ofp,
19051          "table-id %d, prefix %U/%d",
19052          ntohl (mp->table_id), format_ip4_address, mp->address,
19053          mp->address_length);
19054   fp = mp->path;
19055   for (i = 0; i < count; i++)
19056     {
19057       if (fp->afi == IP46_TYPE_IP6)
19058         print (vam->ofp,
19059                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19060                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19061                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19062                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19063                format_ip6_address, fp->next_hop);
19064       else if (fp->afi == IP46_TYPE_IP4)
19065         print (vam->ofp,
19066                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19067                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19068                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19069                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19070                format_ip4_address, fp->next_hop);
19071       fp++;
19072     }
19073 }
19074
19075 static void vl_api_ip_fib_details_t_handler_json
19076   (vl_api_ip_fib_details_t * mp)
19077 {
19078   vat_main_t *vam = &vat_main;
19079   int count = ntohl (mp->count);
19080   vat_json_node_t *node = NULL;
19081   struct in_addr ip4;
19082   struct in6_addr ip6;
19083   vl_api_fib_path_t *fp;
19084   int i;
19085
19086   if (VAT_JSON_ARRAY != vam->json_tree.type)
19087     {
19088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19089       vat_json_init_array (&vam->json_tree);
19090     }
19091   node = vat_json_array_add (&vam->json_tree);
19092
19093   vat_json_init_object (node);
19094   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19095   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19096   vat_json_object_add_ip4 (node, "prefix", ip4);
19097   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19098   vat_json_object_add_uint (node, "path_count", count);
19099   fp = mp->path;
19100   for (i = 0; i < count; i++)
19101     {
19102       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19103       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19104       vat_json_object_add_uint (node, "is_local", fp->is_local);
19105       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19106       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19107       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19108       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19109       if (fp->afi == IP46_TYPE_IP4)
19110         {
19111           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19112           vat_json_object_add_ip4 (node, "next_hop", ip4);
19113         }
19114       else if (fp->afi == IP46_TYPE_IP6)
19115         {
19116           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19117           vat_json_object_add_ip6 (node, "next_hop", ip6);
19118         }
19119     }
19120 }
19121
19122 static int
19123 api_ip_fib_dump (vat_main_t * vam)
19124 {
19125   vl_api_ip_fib_dump_t *mp;
19126   vl_api_control_ping_t *mp_ping;
19127   int ret;
19128
19129   M (IP_FIB_DUMP, mp);
19130   S (mp);
19131
19132   /* Use a control ping for synchronization */
19133   MPING (CONTROL_PING, mp_ping);
19134   S (mp_ping);
19135
19136   W (ret);
19137   return ret;
19138 }
19139
19140 static int
19141 api_ip_mfib_dump (vat_main_t * vam)
19142 {
19143   vl_api_ip_mfib_dump_t *mp;
19144   vl_api_control_ping_t *mp_ping;
19145   int ret;
19146
19147   M (IP_MFIB_DUMP, mp);
19148   S (mp);
19149
19150   /* Use a control ping for synchronization */
19151   MPING (CONTROL_PING, mp_ping);
19152   S (mp_ping);
19153
19154   W (ret);
19155   return ret;
19156 }
19157
19158 static void vl_api_ip_neighbor_details_t_handler
19159   (vl_api_ip_neighbor_details_t * mp)
19160 {
19161   vat_main_t *vam = &vat_main;
19162
19163   print (vam->ofp, "%c %U %U",
19164          (mp->is_static) ? 'S' : 'D',
19165          format_ethernet_address, &mp->mac_address,
19166          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19167          &mp->ip_address);
19168 }
19169
19170 static void vl_api_ip_neighbor_details_t_handler_json
19171   (vl_api_ip_neighbor_details_t * mp)
19172 {
19173
19174   vat_main_t *vam = &vat_main;
19175   vat_json_node_t *node;
19176   struct in_addr ip4;
19177   struct in6_addr ip6;
19178
19179   if (VAT_JSON_ARRAY != vam->json_tree.type)
19180     {
19181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19182       vat_json_init_array (&vam->json_tree);
19183     }
19184   node = vat_json_array_add (&vam->json_tree);
19185
19186   vat_json_init_object (node);
19187   vat_json_object_add_string_copy (node, "flag",
19188                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19189                                    "dynamic");
19190
19191   vat_json_object_add_string_copy (node, "link_layer",
19192                                    format (0, "%U", format_ethernet_address,
19193                                            &mp->mac_address));
19194
19195   if (mp->is_ipv6)
19196     {
19197       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19198       vat_json_object_add_ip6 (node, "ip_address", ip6);
19199     }
19200   else
19201     {
19202       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19203       vat_json_object_add_ip4 (node, "ip_address", ip4);
19204     }
19205 }
19206
19207 static int
19208 api_ip_neighbor_dump (vat_main_t * vam)
19209 {
19210   unformat_input_t *i = vam->input;
19211   vl_api_ip_neighbor_dump_t *mp;
19212   vl_api_control_ping_t *mp_ping;
19213   u8 is_ipv6 = 0;
19214   u32 sw_if_index = ~0;
19215   int ret;
19216
19217   /* Parse args required to build the message */
19218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19219     {
19220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19221         ;
19222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19223         ;
19224       else if (unformat (i, "ip6"))
19225         is_ipv6 = 1;
19226       else
19227         break;
19228     }
19229
19230   if (sw_if_index == ~0)
19231     {
19232       errmsg ("missing interface name or sw_if_index");
19233       return -99;
19234     }
19235
19236   M (IP_NEIGHBOR_DUMP, mp);
19237   mp->is_ipv6 = (u8) is_ipv6;
19238   mp->sw_if_index = ntohl (sw_if_index);
19239   S (mp);
19240
19241   /* Use a control ping for synchronization */
19242   MPING (CONTROL_PING, mp_ping);
19243   S (mp_ping);
19244
19245   W (ret);
19246   return ret;
19247 }
19248
19249 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19250 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19251
19252 static void
19253 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19254 {
19255   vat_main_t *vam = &vat_main;
19256   int count = ntohl (mp->count);
19257   vl_api_fib_path_t *fp;
19258   int i;
19259
19260   print (vam->ofp,
19261          "table-id %d, prefix %U/%d",
19262          ntohl (mp->table_id), format_ip6_address, mp->address,
19263          mp->address_length);
19264   fp = mp->path;
19265   for (i = 0; i < count; i++)
19266     {
19267       if (fp->afi == IP46_TYPE_IP6)
19268         print (vam->ofp,
19269                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19270                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19271                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19272                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19273                format_ip6_address, fp->next_hop);
19274       else if (fp->afi == IP46_TYPE_IP4)
19275         print (vam->ofp,
19276                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19277                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19278                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19279                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19280                format_ip4_address, fp->next_hop);
19281       fp++;
19282     }
19283 }
19284
19285 static void vl_api_ip6_fib_details_t_handler_json
19286   (vl_api_ip6_fib_details_t * mp)
19287 {
19288   vat_main_t *vam = &vat_main;
19289   int count = ntohl (mp->count);
19290   vat_json_node_t *node = NULL;
19291   struct in_addr ip4;
19292   struct in6_addr ip6;
19293   vl_api_fib_path_t *fp;
19294   int i;
19295
19296   if (VAT_JSON_ARRAY != vam->json_tree.type)
19297     {
19298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19299       vat_json_init_array (&vam->json_tree);
19300     }
19301   node = vat_json_array_add (&vam->json_tree);
19302
19303   vat_json_init_object (node);
19304   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19305   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19306   vat_json_object_add_ip6 (node, "prefix", ip6);
19307   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19308   vat_json_object_add_uint (node, "path_count", count);
19309   fp = mp->path;
19310   for (i = 0; i < count; i++)
19311     {
19312       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19313       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19314       vat_json_object_add_uint (node, "is_local", fp->is_local);
19315       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19316       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19317       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19318       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19319       if (fp->afi == IP46_TYPE_IP4)
19320         {
19321           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19322           vat_json_object_add_ip4 (node, "next_hop", ip4);
19323         }
19324       else if (fp->afi == IP46_TYPE_IP6)
19325         {
19326           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19327           vat_json_object_add_ip6 (node, "next_hop", ip6);
19328         }
19329     }
19330 }
19331
19332 static int
19333 api_ip6_fib_dump (vat_main_t * vam)
19334 {
19335   vl_api_ip6_fib_dump_t *mp;
19336   vl_api_control_ping_t *mp_ping;
19337   int ret;
19338
19339   M (IP6_FIB_DUMP, mp);
19340   S (mp);
19341
19342   /* Use a control ping for synchronization */
19343   MPING (CONTROL_PING, mp_ping);
19344   S (mp_ping);
19345
19346   W (ret);
19347   return ret;
19348 }
19349
19350 static int
19351 api_ip6_mfib_dump (vat_main_t * vam)
19352 {
19353   vl_api_ip6_mfib_dump_t *mp;
19354   vl_api_control_ping_t *mp_ping;
19355   int ret;
19356
19357   M (IP6_MFIB_DUMP, mp);
19358   S (mp);
19359
19360   /* Use a control ping for synchronization */
19361   MPING (CONTROL_PING, mp_ping);
19362   S (mp_ping);
19363
19364   W (ret);
19365   return ret;
19366 }
19367
19368 int
19369 api_classify_table_ids (vat_main_t * vam)
19370 {
19371   vl_api_classify_table_ids_t *mp;
19372   int ret;
19373
19374   /* Construct the API message */
19375   M (CLASSIFY_TABLE_IDS, mp);
19376   mp->context = 0;
19377
19378   S (mp);
19379   W (ret);
19380   return ret;
19381 }
19382
19383 int
19384 api_classify_table_by_interface (vat_main_t * vam)
19385 {
19386   unformat_input_t *input = vam->input;
19387   vl_api_classify_table_by_interface_t *mp;
19388
19389   u32 sw_if_index = ~0;
19390   int ret;
19391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19392     {
19393       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19394         ;
19395       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19396         ;
19397       else
19398         break;
19399     }
19400   if (sw_if_index == ~0)
19401     {
19402       errmsg ("missing interface name or sw_if_index");
19403       return -99;
19404     }
19405
19406   /* Construct the API message */
19407   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19408   mp->context = 0;
19409   mp->sw_if_index = ntohl (sw_if_index);
19410
19411   S (mp);
19412   W (ret);
19413   return ret;
19414 }
19415
19416 int
19417 api_classify_table_info (vat_main_t * vam)
19418 {
19419   unformat_input_t *input = vam->input;
19420   vl_api_classify_table_info_t *mp;
19421
19422   u32 table_id = ~0;
19423   int ret;
19424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19425     {
19426       if (unformat (input, "table_id %d", &table_id))
19427         ;
19428       else
19429         break;
19430     }
19431   if (table_id == ~0)
19432     {
19433       errmsg ("missing table id");
19434       return -99;
19435     }
19436
19437   /* Construct the API message */
19438   M (CLASSIFY_TABLE_INFO, mp);
19439   mp->context = 0;
19440   mp->table_id = ntohl (table_id);
19441
19442   S (mp);
19443   W (ret);
19444   return ret;
19445 }
19446
19447 int
19448 api_classify_session_dump (vat_main_t * vam)
19449 {
19450   unformat_input_t *input = vam->input;
19451   vl_api_classify_session_dump_t *mp;
19452   vl_api_control_ping_t *mp_ping;
19453
19454   u32 table_id = ~0;
19455   int ret;
19456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19457     {
19458       if (unformat (input, "table_id %d", &table_id))
19459         ;
19460       else
19461         break;
19462     }
19463   if (table_id == ~0)
19464     {
19465       errmsg ("missing table id");
19466       return -99;
19467     }
19468
19469   /* Construct the API message */
19470   M (CLASSIFY_SESSION_DUMP, mp);
19471   mp->context = 0;
19472   mp->table_id = ntohl (table_id);
19473   S (mp);
19474
19475   /* Use a control ping for synchronization */
19476   MPING (CONTROL_PING, mp_ping);
19477   S (mp_ping);
19478
19479   W (ret);
19480   return ret;
19481 }
19482
19483 static void
19484 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19485 {
19486   vat_main_t *vam = &vat_main;
19487
19488   print (vam->ofp, "collector_address %U, collector_port %d, "
19489          "src_address %U, vrf_id %d, path_mtu %u, "
19490          "template_interval %u, udp_checksum %d",
19491          format_ip4_address, mp->collector_address,
19492          ntohs (mp->collector_port),
19493          format_ip4_address, mp->src_address,
19494          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19495          ntohl (mp->template_interval), mp->udp_checksum);
19496
19497   vam->retval = 0;
19498   vam->result_ready = 1;
19499 }
19500
19501 static void
19502   vl_api_ipfix_exporter_details_t_handler_json
19503   (vl_api_ipfix_exporter_details_t * mp)
19504 {
19505   vat_main_t *vam = &vat_main;
19506   vat_json_node_t node;
19507   struct in_addr collector_address;
19508   struct in_addr src_address;
19509
19510   vat_json_init_object (&node);
19511   clib_memcpy (&collector_address, &mp->collector_address,
19512                sizeof (collector_address));
19513   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19514   vat_json_object_add_uint (&node, "collector_port",
19515                             ntohs (mp->collector_port));
19516   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19517   vat_json_object_add_ip4 (&node, "src_address", src_address);
19518   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19519   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19520   vat_json_object_add_uint (&node, "template_interval",
19521                             ntohl (mp->template_interval));
19522   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19523
19524   vat_json_print (vam->ofp, &node);
19525   vat_json_free (&node);
19526   vam->retval = 0;
19527   vam->result_ready = 1;
19528 }
19529
19530 int
19531 api_ipfix_exporter_dump (vat_main_t * vam)
19532 {
19533   vl_api_ipfix_exporter_dump_t *mp;
19534   int ret;
19535
19536   /* Construct the API message */
19537   M (IPFIX_EXPORTER_DUMP, mp);
19538   mp->context = 0;
19539
19540   S (mp);
19541   W (ret);
19542   return ret;
19543 }
19544
19545 static int
19546 api_ipfix_classify_stream_dump (vat_main_t * vam)
19547 {
19548   vl_api_ipfix_classify_stream_dump_t *mp;
19549   int ret;
19550
19551   /* Construct the API message */
19552   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19553   mp->context = 0;
19554
19555   S (mp);
19556   W (ret);
19557   return ret;
19558   /* NOTREACHED */
19559   return 0;
19560 }
19561
19562 static void
19563   vl_api_ipfix_classify_stream_details_t_handler
19564   (vl_api_ipfix_classify_stream_details_t * mp)
19565 {
19566   vat_main_t *vam = &vat_main;
19567   print (vam->ofp, "domain_id %d, src_port %d",
19568          ntohl (mp->domain_id), ntohs (mp->src_port));
19569   vam->retval = 0;
19570   vam->result_ready = 1;
19571 }
19572
19573 static void
19574   vl_api_ipfix_classify_stream_details_t_handler_json
19575   (vl_api_ipfix_classify_stream_details_t * mp)
19576 {
19577   vat_main_t *vam = &vat_main;
19578   vat_json_node_t node;
19579
19580   vat_json_init_object (&node);
19581   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19582   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19583
19584   vat_json_print (vam->ofp, &node);
19585   vat_json_free (&node);
19586   vam->retval = 0;
19587   vam->result_ready = 1;
19588 }
19589
19590 static int
19591 api_ipfix_classify_table_dump (vat_main_t * vam)
19592 {
19593   vl_api_ipfix_classify_table_dump_t *mp;
19594   vl_api_control_ping_t *mp_ping;
19595   int ret;
19596
19597   if (!vam->json_output)
19598     {
19599       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19600              "transport_protocol");
19601     }
19602
19603   /* Construct the API message */
19604   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19605
19606   /* send it... */
19607   S (mp);
19608
19609   /* Use a control ping for synchronization */
19610   MPING (CONTROL_PING, mp_ping);
19611   S (mp_ping);
19612
19613   W (ret);
19614   return ret;
19615 }
19616
19617 static void
19618   vl_api_ipfix_classify_table_details_t_handler
19619   (vl_api_ipfix_classify_table_details_t * mp)
19620 {
19621   vat_main_t *vam = &vat_main;
19622   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19623          mp->transport_protocol);
19624 }
19625
19626 static void
19627   vl_api_ipfix_classify_table_details_t_handler_json
19628   (vl_api_ipfix_classify_table_details_t * mp)
19629 {
19630   vat_json_node_t *node = NULL;
19631   vat_main_t *vam = &vat_main;
19632
19633   if (VAT_JSON_ARRAY != vam->json_tree.type)
19634     {
19635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19636       vat_json_init_array (&vam->json_tree);
19637     }
19638
19639   node = vat_json_array_add (&vam->json_tree);
19640   vat_json_init_object (node);
19641
19642   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19643   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19644   vat_json_object_add_uint (node, "transport_protocol",
19645                             mp->transport_protocol);
19646 }
19647
19648 static int
19649 api_sw_interface_span_enable_disable (vat_main_t * vam)
19650 {
19651   unformat_input_t *i = vam->input;
19652   vl_api_sw_interface_span_enable_disable_t *mp;
19653   u32 src_sw_if_index = ~0;
19654   u32 dst_sw_if_index = ~0;
19655   u8 state = 3;
19656   int ret;
19657   u8 is_l2 = 0;
19658
19659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19660     {
19661       if (unformat
19662           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19663         ;
19664       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19665         ;
19666       else
19667         if (unformat
19668             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19669         ;
19670       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19671         ;
19672       else if (unformat (i, "disable"))
19673         state = 0;
19674       else if (unformat (i, "rx"))
19675         state = 1;
19676       else if (unformat (i, "tx"))
19677         state = 2;
19678       else if (unformat (i, "both"))
19679         state = 3;
19680       else if (unformat (i, "l2"))
19681         is_l2 = 1;
19682       else
19683         break;
19684     }
19685
19686   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19687
19688   mp->sw_if_index_from = htonl (src_sw_if_index);
19689   mp->sw_if_index_to = htonl (dst_sw_if_index);
19690   mp->state = state;
19691   mp->is_l2 = is_l2;
19692
19693   S (mp);
19694   W (ret);
19695   return ret;
19696 }
19697
19698 static void
19699 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19700                                             * mp)
19701 {
19702   vat_main_t *vam = &vat_main;
19703   u8 *sw_if_from_name = 0;
19704   u8 *sw_if_to_name = 0;
19705   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19706   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19707   char *states[] = { "none", "rx", "tx", "both" };
19708   hash_pair_t *p;
19709
19710   /* *INDENT-OFF* */
19711   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19712   ({
19713     if ((u32) p->value[0] == sw_if_index_from)
19714       {
19715         sw_if_from_name = (u8 *)(p->key);
19716         if (sw_if_to_name)
19717           break;
19718       }
19719     if ((u32) p->value[0] == sw_if_index_to)
19720       {
19721         sw_if_to_name = (u8 *)(p->key);
19722         if (sw_if_from_name)
19723           break;
19724       }
19725   }));
19726   /* *INDENT-ON* */
19727   print (vam->ofp, "%20s => %20s (%s)",
19728          sw_if_from_name, sw_if_to_name, states[mp->state]);
19729 }
19730
19731 static void
19732   vl_api_sw_interface_span_details_t_handler_json
19733   (vl_api_sw_interface_span_details_t * mp)
19734 {
19735   vat_main_t *vam = &vat_main;
19736   vat_json_node_t *node = NULL;
19737   u8 *sw_if_from_name = 0;
19738   u8 *sw_if_to_name = 0;
19739   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19740   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19741   hash_pair_t *p;
19742
19743   /* *INDENT-OFF* */
19744   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19745   ({
19746     if ((u32) p->value[0] == sw_if_index_from)
19747       {
19748         sw_if_from_name = (u8 *)(p->key);
19749         if (sw_if_to_name)
19750           break;
19751       }
19752     if ((u32) p->value[0] == sw_if_index_to)
19753       {
19754         sw_if_to_name = (u8 *)(p->key);
19755         if (sw_if_from_name)
19756           break;
19757       }
19758   }));
19759   /* *INDENT-ON* */
19760
19761   if (VAT_JSON_ARRAY != vam->json_tree.type)
19762     {
19763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19764       vat_json_init_array (&vam->json_tree);
19765     }
19766   node = vat_json_array_add (&vam->json_tree);
19767
19768   vat_json_init_object (node);
19769   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19770   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19771   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19772   if (0 != sw_if_to_name)
19773     {
19774       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19775     }
19776   vat_json_object_add_uint (node, "state", mp->state);
19777 }
19778
19779 static int
19780 api_sw_interface_span_dump (vat_main_t * vam)
19781 {
19782   unformat_input_t *input = vam->input;
19783   vl_api_sw_interface_span_dump_t *mp;
19784   vl_api_control_ping_t *mp_ping;
19785   u8 is_l2 = 0;
19786   int ret;
19787
19788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19789     {
19790       if (unformat (input, "l2"))
19791         is_l2 = 1;
19792       else
19793         break;
19794     }
19795
19796   M (SW_INTERFACE_SPAN_DUMP, mp);
19797   mp->is_l2 = is_l2;
19798   S (mp);
19799
19800   /* Use a control ping for synchronization */
19801   MPING (CONTROL_PING, mp_ping);
19802   S (mp_ping);
19803
19804   W (ret);
19805   return ret;
19806 }
19807
19808 int
19809 api_pg_create_interface (vat_main_t * vam)
19810 {
19811   unformat_input_t *input = vam->input;
19812   vl_api_pg_create_interface_t *mp;
19813
19814   u32 if_id = ~0;
19815   int ret;
19816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19817     {
19818       if (unformat (input, "if_id %d", &if_id))
19819         ;
19820       else
19821         break;
19822     }
19823   if (if_id == ~0)
19824     {
19825       errmsg ("missing pg interface index");
19826       return -99;
19827     }
19828
19829   /* Construct the API message */
19830   M (PG_CREATE_INTERFACE, mp);
19831   mp->context = 0;
19832   mp->interface_id = ntohl (if_id);
19833
19834   S (mp);
19835   W (ret);
19836   return ret;
19837 }
19838
19839 int
19840 api_pg_capture (vat_main_t * vam)
19841 {
19842   unformat_input_t *input = vam->input;
19843   vl_api_pg_capture_t *mp;
19844
19845   u32 if_id = ~0;
19846   u8 enable = 1;
19847   u32 count = 1;
19848   u8 pcap_file_set = 0;
19849   u8 *pcap_file = 0;
19850   int ret;
19851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19852     {
19853       if (unformat (input, "if_id %d", &if_id))
19854         ;
19855       else if (unformat (input, "pcap %s", &pcap_file))
19856         pcap_file_set = 1;
19857       else if (unformat (input, "count %d", &count))
19858         ;
19859       else if (unformat (input, "disable"))
19860         enable = 0;
19861       else
19862         break;
19863     }
19864   if (if_id == ~0)
19865     {
19866       errmsg ("missing pg interface index");
19867       return -99;
19868     }
19869   if (pcap_file_set > 0)
19870     {
19871       if (vec_len (pcap_file) > 255)
19872         {
19873           errmsg ("pcap file name is too long");
19874           return -99;
19875         }
19876     }
19877
19878   u32 name_len = vec_len (pcap_file);
19879   /* Construct the API message */
19880   M (PG_CAPTURE, mp);
19881   mp->context = 0;
19882   mp->interface_id = ntohl (if_id);
19883   mp->is_enabled = enable;
19884   mp->count = ntohl (count);
19885   mp->pcap_name_length = ntohl (name_len);
19886   if (pcap_file_set != 0)
19887     {
19888       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19889     }
19890   vec_free (pcap_file);
19891
19892   S (mp);
19893   W (ret);
19894   return ret;
19895 }
19896
19897 int
19898 api_pg_enable_disable (vat_main_t * vam)
19899 {
19900   unformat_input_t *input = vam->input;
19901   vl_api_pg_enable_disable_t *mp;
19902
19903   u8 enable = 1;
19904   u8 stream_name_set = 0;
19905   u8 *stream_name = 0;
19906   int ret;
19907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19908     {
19909       if (unformat (input, "stream %s", &stream_name))
19910         stream_name_set = 1;
19911       else if (unformat (input, "disable"))
19912         enable = 0;
19913       else
19914         break;
19915     }
19916
19917   if (stream_name_set > 0)
19918     {
19919       if (vec_len (stream_name) > 255)
19920         {
19921           errmsg ("stream name too long");
19922           return -99;
19923         }
19924     }
19925
19926   u32 name_len = vec_len (stream_name);
19927   /* Construct the API message */
19928   M (PG_ENABLE_DISABLE, mp);
19929   mp->context = 0;
19930   mp->is_enabled = enable;
19931   if (stream_name_set != 0)
19932     {
19933       mp->stream_name_length = ntohl (name_len);
19934       clib_memcpy (mp->stream_name, stream_name, name_len);
19935     }
19936   vec_free (stream_name);
19937
19938   S (mp);
19939   W (ret);
19940   return ret;
19941 }
19942
19943 int
19944 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19945 {
19946   unformat_input_t *input = vam->input;
19947   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19948
19949   u16 *low_ports = 0;
19950   u16 *high_ports = 0;
19951   u16 this_low;
19952   u16 this_hi;
19953   ip4_address_t ip4_addr;
19954   ip6_address_t ip6_addr;
19955   u32 length;
19956   u32 tmp, tmp2;
19957   u8 prefix_set = 0;
19958   u32 vrf_id = ~0;
19959   u8 is_add = 1;
19960   u8 is_ipv6 = 0;
19961   int ret;
19962
19963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19964     {
19965       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19966         {
19967           prefix_set = 1;
19968         }
19969       else
19970         if (unformat
19971             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19972         {
19973           prefix_set = 1;
19974           is_ipv6 = 1;
19975         }
19976       else if (unformat (input, "vrf %d", &vrf_id))
19977         ;
19978       else if (unformat (input, "del"))
19979         is_add = 0;
19980       else if (unformat (input, "port %d", &tmp))
19981         {
19982           if (tmp == 0 || tmp > 65535)
19983             {
19984               errmsg ("port %d out of range", tmp);
19985               return -99;
19986             }
19987           this_low = tmp;
19988           this_hi = this_low + 1;
19989           vec_add1 (low_ports, this_low);
19990           vec_add1 (high_ports, this_hi);
19991         }
19992       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19993         {
19994           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19995             {
19996               errmsg ("incorrect range parameters");
19997               return -99;
19998             }
19999           this_low = tmp;
20000           /* Note: in debug CLI +1 is added to high before
20001              passing to real fn that does "the work"
20002              (ip_source_and_port_range_check_add_del).
20003              This fn is a wrapper around the binary API fn a
20004              control plane will call, which expects this increment
20005              to have occurred. Hence letting the binary API control
20006              plane fn do the increment for consistency between VAT
20007              and other control planes.
20008            */
20009           this_hi = tmp2;
20010           vec_add1 (low_ports, this_low);
20011           vec_add1 (high_ports, this_hi);
20012         }
20013       else
20014         break;
20015     }
20016
20017   if (prefix_set == 0)
20018     {
20019       errmsg ("<address>/<mask> not specified");
20020       return -99;
20021     }
20022
20023   if (vrf_id == ~0)
20024     {
20025       errmsg ("VRF ID required, not specified");
20026       return -99;
20027     }
20028
20029   if (vrf_id == 0)
20030     {
20031       errmsg
20032         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20033       return -99;
20034     }
20035
20036   if (vec_len (low_ports) == 0)
20037     {
20038       errmsg ("At least one port or port range required");
20039       return -99;
20040     }
20041
20042   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20043
20044   mp->is_add = is_add;
20045
20046   if (is_ipv6)
20047     {
20048       mp->is_ipv6 = 1;
20049       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20050     }
20051   else
20052     {
20053       mp->is_ipv6 = 0;
20054       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20055     }
20056
20057   mp->mask_length = length;
20058   mp->number_of_ranges = vec_len (low_ports);
20059
20060   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20061   vec_free (low_ports);
20062
20063   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20064   vec_free (high_ports);
20065
20066   mp->vrf_id = ntohl (vrf_id);
20067
20068   S (mp);
20069   W (ret);
20070   return ret;
20071 }
20072
20073 int
20074 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20075 {
20076   unformat_input_t *input = vam->input;
20077   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20078   u32 sw_if_index = ~0;
20079   int vrf_set = 0;
20080   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20081   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20082   u8 is_add = 1;
20083   int ret;
20084
20085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20086     {
20087       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20088         ;
20089       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20090         ;
20091       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20092         vrf_set = 1;
20093       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20094         vrf_set = 1;
20095       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20096         vrf_set = 1;
20097       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20098         vrf_set = 1;
20099       else if (unformat (input, "del"))
20100         is_add = 0;
20101       else
20102         break;
20103     }
20104
20105   if (sw_if_index == ~0)
20106     {
20107       errmsg ("Interface required but not specified");
20108       return -99;
20109     }
20110
20111   if (vrf_set == 0)
20112     {
20113       errmsg ("VRF ID required but not specified");
20114       return -99;
20115     }
20116
20117   if (tcp_out_vrf_id == 0
20118       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20119     {
20120       errmsg
20121         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20122       return -99;
20123     }
20124
20125   /* Construct the API message */
20126   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20127
20128   mp->sw_if_index = ntohl (sw_if_index);
20129   mp->is_add = is_add;
20130   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20131   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20132   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20133   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20134
20135   /* send it... */
20136   S (mp);
20137
20138   /* Wait for a reply... */
20139   W (ret);
20140   return ret;
20141 }
20142
20143 static int
20144 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20145 {
20146   unformat_input_t *i = vam->input;
20147   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20148   u32 local_sa_id = 0;
20149   u32 remote_sa_id = 0;
20150   ip4_address_t src_address;
20151   ip4_address_t dst_address;
20152   u8 is_add = 1;
20153   int ret;
20154
20155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20156     {
20157       if (unformat (i, "local_sa %d", &local_sa_id))
20158         ;
20159       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20160         ;
20161       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20162         ;
20163       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20164         ;
20165       else if (unformat (i, "del"))
20166         is_add = 0;
20167       else
20168         {
20169           clib_warning ("parse error '%U'", format_unformat_error, i);
20170           return -99;
20171         }
20172     }
20173
20174   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20175
20176   mp->local_sa_id = ntohl (local_sa_id);
20177   mp->remote_sa_id = ntohl (remote_sa_id);
20178   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20179   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20180   mp->is_add = is_add;
20181
20182   S (mp);
20183   W (ret);
20184   return ret;
20185 }
20186
20187 static int
20188 api_punt (vat_main_t * vam)
20189 {
20190   unformat_input_t *i = vam->input;
20191   vl_api_punt_t *mp;
20192   u32 ipv = ~0;
20193   u32 protocol = ~0;
20194   u32 port = ~0;
20195   int is_add = 1;
20196   int ret;
20197
20198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20199     {
20200       if (unformat (i, "ip %d", &ipv))
20201         ;
20202       else if (unformat (i, "protocol %d", &protocol))
20203         ;
20204       else if (unformat (i, "port %d", &port))
20205         ;
20206       else if (unformat (i, "del"))
20207         is_add = 0;
20208       else
20209         {
20210           clib_warning ("parse error '%U'", format_unformat_error, i);
20211           return -99;
20212         }
20213     }
20214
20215   M (PUNT, mp);
20216
20217   mp->is_add = (u8) is_add;
20218   mp->ipv = (u8) ipv;
20219   mp->l4_protocol = (u8) protocol;
20220   mp->l4_port = htons ((u16) port);
20221
20222   S (mp);
20223   W (ret);
20224   return ret;
20225 }
20226
20227 static void vl_api_ipsec_gre_tunnel_details_t_handler
20228   (vl_api_ipsec_gre_tunnel_details_t * mp)
20229 {
20230   vat_main_t *vam = &vat_main;
20231
20232   print (vam->ofp, "%11d%15U%15U%14d%14d",
20233          ntohl (mp->sw_if_index),
20234          format_ip4_address, &mp->src_address,
20235          format_ip4_address, &mp->dst_address,
20236          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20237 }
20238
20239 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20240   (vl_api_ipsec_gre_tunnel_details_t * mp)
20241 {
20242   vat_main_t *vam = &vat_main;
20243   vat_json_node_t *node = NULL;
20244   struct in_addr ip4;
20245
20246   if (VAT_JSON_ARRAY != vam->json_tree.type)
20247     {
20248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20249       vat_json_init_array (&vam->json_tree);
20250     }
20251   node = vat_json_array_add (&vam->json_tree);
20252
20253   vat_json_init_object (node);
20254   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20255   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20256   vat_json_object_add_ip4 (node, "src_address", ip4);
20257   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20258   vat_json_object_add_ip4 (node, "dst_address", ip4);
20259   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20260   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20261 }
20262
20263 static int
20264 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20265 {
20266   unformat_input_t *i = vam->input;
20267   vl_api_ipsec_gre_tunnel_dump_t *mp;
20268   vl_api_control_ping_t *mp_ping;
20269   u32 sw_if_index;
20270   u8 sw_if_index_set = 0;
20271   int ret;
20272
20273   /* Parse args required to build the message */
20274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20275     {
20276       if (unformat (i, "sw_if_index %d", &sw_if_index))
20277         sw_if_index_set = 1;
20278       else
20279         break;
20280     }
20281
20282   if (sw_if_index_set == 0)
20283     {
20284       sw_if_index = ~0;
20285     }
20286
20287   if (!vam->json_output)
20288     {
20289       print (vam->ofp, "%11s%15s%15s%14s%14s",
20290              "sw_if_index", "src_address", "dst_address",
20291              "local_sa_id", "remote_sa_id");
20292     }
20293
20294   /* Get list of gre-tunnel interfaces */
20295   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20296
20297   mp->sw_if_index = htonl (sw_if_index);
20298
20299   S (mp);
20300
20301   /* Use a control ping for synchronization */
20302   MPING (CONTROL_PING, mp_ping);
20303   S (mp_ping);
20304
20305   W (ret);
20306   return ret;
20307 }
20308
20309 static int
20310 api_delete_subif (vat_main_t * vam)
20311 {
20312   unformat_input_t *i = vam->input;
20313   vl_api_delete_subif_t *mp;
20314   u32 sw_if_index = ~0;
20315   int ret;
20316
20317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20318     {
20319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20320         ;
20321       if (unformat (i, "sw_if_index %d", &sw_if_index))
20322         ;
20323       else
20324         break;
20325     }
20326
20327   if (sw_if_index == ~0)
20328     {
20329       errmsg ("missing sw_if_index");
20330       return -99;
20331     }
20332
20333   /* Construct the API message */
20334   M (DELETE_SUBIF, mp);
20335   mp->sw_if_index = ntohl (sw_if_index);
20336
20337   S (mp);
20338   W (ret);
20339   return ret;
20340 }
20341
20342 #define foreach_pbb_vtr_op      \
20343 _("disable",  L2_VTR_DISABLED)  \
20344 _("pop",  L2_VTR_POP_2)         \
20345 _("push",  L2_VTR_PUSH_2)
20346
20347 static int
20348 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20349 {
20350   unformat_input_t *i = vam->input;
20351   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20352   u32 sw_if_index = ~0, vtr_op = ~0;
20353   u16 outer_tag = ~0;
20354   u8 dmac[6], smac[6];
20355   u8 dmac_set = 0, smac_set = 0;
20356   u16 vlanid = 0;
20357   u32 sid = ~0;
20358   u32 tmp;
20359   int ret;
20360
20361   /* Shut up coverity */
20362   memset (dmac, 0, sizeof (dmac));
20363   memset (smac, 0, sizeof (smac));
20364
20365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20366     {
20367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20368         ;
20369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20370         ;
20371       else if (unformat (i, "vtr_op %d", &vtr_op))
20372         ;
20373 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20374       foreach_pbb_vtr_op
20375 #undef _
20376         else if (unformat (i, "translate_pbb_stag"))
20377         {
20378           if (unformat (i, "%d", &tmp))
20379             {
20380               vtr_op = L2_VTR_TRANSLATE_2_1;
20381               outer_tag = tmp;
20382             }
20383           else
20384             {
20385               errmsg
20386                 ("translate_pbb_stag operation requires outer tag definition");
20387               return -99;
20388             }
20389         }
20390       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20391         dmac_set++;
20392       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20393         smac_set++;
20394       else if (unformat (i, "sid %d", &sid))
20395         ;
20396       else if (unformat (i, "vlanid %d", &tmp))
20397         vlanid = tmp;
20398       else
20399         {
20400           clib_warning ("parse error '%U'", format_unformat_error, i);
20401           return -99;
20402         }
20403     }
20404
20405   if ((sw_if_index == ~0) || (vtr_op == ~0))
20406     {
20407       errmsg ("missing sw_if_index or vtr operation");
20408       return -99;
20409     }
20410   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20411       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20412     {
20413       errmsg
20414         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20415       return -99;
20416     }
20417
20418   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20419   mp->sw_if_index = ntohl (sw_if_index);
20420   mp->vtr_op = ntohl (vtr_op);
20421   mp->outer_tag = ntohs (outer_tag);
20422   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20423   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20424   mp->b_vlanid = ntohs (vlanid);
20425   mp->i_sid = ntohl (sid);
20426
20427   S (mp);
20428   W (ret);
20429   return ret;
20430 }
20431
20432 static int
20433 api_flow_classify_set_interface (vat_main_t * vam)
20434 {
20435   unformat_input_t *i = vam->input;
20436   vl_api_flow_classify_set_interface_t *mp;
20437   u32 sw_if_index;
20438   int sw_if_index_set;
20439   u32 ip4_table_index = ~0;
20440   u32 ip6_table_index = ~0;
20441   u8 is_add = 1;
20442   int ret;
20443
20444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20445     {
20446       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20447         sw_if_index_set = 1;
20448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20449         sw_if_index_set = 1;
20450       else if (unformat (i, "del"))
20451         is_add = 0;
20452       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20453         ;
20454       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20455         ;
20456       else
20457         {
20458           clib_warning ("parse error '%U'", format_unformat_error, i);
20459           return -99;
20460         }
20461     }
20462
20463   if (sw_if_index_set == 0)
20464     {
20465       errmsg ("missing interface name or sw_if_index");
20466       return -99;
20467     }
20468
20469   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20470
20471   mp->sw_if_index = ntohl (sw_if_index);
20472   mp->ip4_table_index = ntohl (ip4_table_index);
20473   mp->ip6_table_index = ntohl (ip6_table_index);
20474   mp->is_add = is_add;
20475
20476   S (mp);
20477   W (ret);
20478   return ret;
20479 }
20480
20481 static int
20482 api_flow_classify_dump (vat_main_t * vam)
20483 {
20484   unformat_input_t *i = vam->input;
20485   vl_api_flow_classify_dump_t *mp;
20486   vl_api_control_ping_t *mp_ping;
20487   u8 type = FLOW_CLASSIFY_N_TABLES;
20488   int ret;
20489
20490   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20491     ;
20492   else
20493     {
20494       errmsg ("classify table type must be specified");
20495       return -99;
20496     }
20497
20498   if (!vam->json_output)
20499     {
20500       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20501     }
20502
20503   M (FLOW_CLASSIFY_DUMP, mp);
20504   mp->type = type;
20505   /* send it... */
20506   S (mp);
20507
20508   /* Use a control ping for synchronization */
20509   MPING (CONTROL_PING, mp_ping);
20510   S (mp_ping);
20511
20512   /* Wait for a reply... */
20513   W (ret);
20514   return ret;
20515 }
20516
20517 static int
20518 api_feature_enable_disable (vat_main_t * vam)
20519 {
20520   unformat_input_t *i = vam->input;
20521   vl_api_feature_enable_disable_t *mp;
20522   u8 *arc_name = 0;
20523   u8 *feature_name = 0;
20524   u32 sw_if_index = ~0;
20525   u8 enable = 1;
20526   int ret;
20527
20528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20529     {
20530       if (unformat (i, "arc_name %s", &arc_name))
20531         ;
20532       else if (unformat (i, "feature_name %s", &feature_name))
20533         ;
20534       else
20535         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20536         ;
20537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20538         ;
20539       else if (unformat (i, "disable"))
20540         enable = 0;
20541       else
20542         break;
20543     }
20544
20545   if (arc_name == 0)
20546     {
20547       errmsg ("missing arc name");
20548       return -99;
20549     }
20550   if (vec_len (arc_name) > 63)
20551     {
20552       errmsg ("arc name too long");
20553     }
20554
20555   if (feature_name == 0)
20556     {
20557       errmsg ("missing feature name");
20558       return -99;
20559     }
20560   if (vec_len (feature_name) > 63)
20561     {
20562       errmsg ("feature name too long");
20563     }
20564
20565   if (sw_if_index == ~0)
20566     {
20567       errmsg ("missing interface name or sw_if_index");
20568       return -99;
20569     }
20570
20571   /* Construct the API message */
20572   M (FEATURE_ENABLE_DISABLE, mp);
20573   mp->sw_if_index = ntohl (sw_if_index);
20574   mp->enable = enable;
20575   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20576   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20577   vec_free (arc_name);
20578   vec_free (feature_name);
20579
20580   S (mp);
20581   W (ret);
20582   return ret;
20583 }
20584
20585 static int
20586 api_sw_interface_tag_add_del (vat_main_t * vam)
20587 {
20588   unformat_input_t *i = vam->input;
20589   vl_api_sw_interface_tag_add_del_t *mp;
20590   u32 sw_if_index = ~0;
20591   u8 *tag = 0;
20592   u8 enable = 1;
20593   int ret;
20594
20595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20596     {
20597       if (unformat (i, "tag %s", &tag))
20598         ;
20599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20600         ;
20601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20602         ;
20603       else if (unformat (i, "del"))
20604         enable = 0;
20605       else
20606         break;
20607     }
20608
20609   if (sw_if_index == ~0)
20610     {
20611       errmsg ("missing interface name or sw_if_index");
20612       return -99;
20613     }
20614
20615   if (enable && (tag == 0))
20616     {
20617       errmsg ("no tag specified");
20618       return -99;
20619     }
20620
20621   /* Construct the API message */
20622   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20623   mp->sw_if_index = ntohl (sw_if_index);
20624   mp->is_add = enable;
20625   if (enable)
20626     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20627   vec_free (tag);
20628
20629   S (mp);
20630   W (ret);
20631   return ret;
20632 }
20633
20634 static void vl_api_l2_xconnect_details_t_handler
20635   (vl_api_l2_xconnect_details_t * mp)
20636 {
20637   vat_main_t *vam = &vat_main;
20638
20639   print (vam->ofp, "%15d%15d",
20640          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20641 }
20642
20643 static void vl_api_l2_xconnect_details_t_handler_json
20644   (vl_api_l2_xconnect_details_t * mp)
20645 {
20646   vat_main_t *vam = &vat_main;
20647   vat_json_node_t *node = NULL;
20648
20649   if (VAT_JSON_ARRAY != vam->json_tree.type)
20650     {
20651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20652       vat_json_init_array (&vam->json_tree);
20653     }
20654   node = vat_json_array_add (&vam->json_tree);
20655
20656   vat_json_init_object (node);
20657   vat_json_object_add_uint (node, "rx_sw_if_index",
20658                             ntohl (mp->rx_sw_if_index));
20659   vat_json_object_add_uint (node, "tx_sw_if_index",
20660                             ntohl (mp->tx_sw_if_index));
20661 }
20662
20663 static int
20664 api_l2_xconnect_dump (vat_main_t * vam)
20665 {
20666   vl_api_l2_xconnect_dump_t *mp;
20667   vl_api_control_ping_t *mp_ping;
20668   int ret;
20669
20670   if (!vam->json_output)
20671     {
20672       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20673     }
20674
20675   M (L2_XCONNECT_DUMP, mp);
20676
20677   S (mp);
20678
20679   /* Use a control ping for synchronization */
20680   MPING (CONTROL_PING, mp_ping);
20681   S (mp_ping);
20682
20683   W (ret);
20684   return ret;
20685 }
20686
20687 static int
20688 api_sw_interface_set_mtu (vat_main_t * vam)
20689 {
20690   unformat_input_t *i = vam->input;
20691   vl_api_sw_interface_set_mtu_t *mp;
20692   u32 sw_if_index = ~0;
20693   u32 mtu = 0;
20694   int ret;
20695
20696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20697     {
20698       if (unformat (i, "mtu %d", &mtu))
20699         ;
20700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20701         ;
20702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20703         ;
20704       else
20705         break;
20706     }
20707
20708   if (sw_if_index == ~0)
20709     {
20710       errmsg ("missing interface name or sw_if_index");
20711       return -99;
20712     }
20713
20714   if (mtu == 0)
20715     {
20716       errmsg ("no mtu specified");
20717       return -99;
20718     }
20719
20720   /* Construct the API message */
20721   M (SW_INTERFACE_SET_MTU, mp);
20722   mp->sw_if_index = ntohl (sw_if_index);
20723   mp->mtu = ntohs ((u16) mtu);
20724
20725   S (mp);
20726   W (ret);
20727   return ret;
20728 }
20729
20730 static int
20731 api_p2p_ethernet_add (vat_main_t * vam)
20732 {
20733   unformat_input_t *i = vam->input;
20734   vl_api_p2p_ethernet_add_t *mp;
20735   u32 parent_if_index = ~0;
20736   u32 sub_id = ~0;
20737   u8 remote_mac[6];
20738   u8 mac_set = 0;
20739   int ret;
20740
20741   memset (remote_mac, 0, sizeof (remote_mac));
20742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20743     {
20744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20745         ;
20746       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20747         ;
20748       else
20749         if (unformat
20750             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20751         mac_set++;
20752       else if (unformat (i, "sub_id %d", &sub_id))
20753         ;
20754       else
20755         {
20756           clib_warning ("parse error '%U'", format_unformat_error, i);
20757           return -99;
20758         }
20759     }
20760
20761   if (parent_if_index == ~0)
20762     {
20763       errmsg ("missing interface name or sw_if_index");
20764       return -99;
20765     }
20766   if (mac_set == 0)
20767     {
20768       errmsg ("missing remote mac address");
20769       return -99;
20770     }
20771   if (sub_id == ~0)
20772     {
20773       errmsg ("missing sub-interface id");
20774       return -99;
20775     }
20776
20777   M (P2P_ETHERNET_ADD, mp);
20778   mp->parent_if_index = ntohl (parent_if_index);
20779   mp->subif_id = ntohl (sub_id);
20780   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20781
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static int
20788 api_p2p_ethernet_del (vat_main_t * vam)
20789 {
20790   unformat_input_t *i = vam->input;
20791   vl_api_p2p_ethernet_del_t *mp;
20792   u32 parent_if_index = ~0;
20793   u8 remote_mac[6];
20794   u8 mac_set = 0;
20795   int ret;
20796
20797   memset (remote_mac, 0, sizeof (remote_mac));
20798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20799     {
20800       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20801         ;
20802       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20803         ;
20804       else
20805         if (unformat
20806             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20807         mac_set++;
20808       else
20809         {
20810           clib_warning ("parse error '%U'", format_unformat_error, i);
20811           return -99;
20812         }
20813     }
20814
20815   if (parent_if_index == ~0)
20816     {
20817       errmsg ("missing interface name or sw_if_index");
20818       return -99;
20819     }
20820   if (mac_set == 0)
20821     {
20822       errmsg ("missing remote mac address");
20823       return -99;
20824     }
20825
20826   M (P2P_ETHERNET_DEL, mp);
20827   mp->parent_if_index = ntohl (parent_if_index);
20828   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20829
20830   S (mp);
20831   W (ret);
20832   return ret;
20833 }
20834
20835 static int
20836 api_lldp_config (vat_main_t * vam)
20837 {
20838   unformat_input_t *i = vam->input;
20839   vl_api_lldp_config_t *mp;
20840   int tx_hold = 0;
20841   int tx_interval = 0;
20842   u8 *sys_name = NULL;
20843   int ret;
20844
20845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20846     {
20847       if (unformat (i, "system-name %s", &sys_name))
20848         ;
20849       else if (unformat (i, "tx-hold %d", &tx_hold))
20850         ;
20851       else if (unformat (i, "tx-interval %d", &tx_interval))
20852         ;
20853       else
20854         {
20855           clib_warning ("parse error '%U'", format_unformat_error, i);
20856           return -99;
20857         }
20858     }
20859
20860   vec_add1 (sys_name, 0);
20861
20862   M (LLDP_CONFIG, mp);
20863   mp->tx_hold = htonl (tx_hold);
20864   mp->tx_interval = htonl (tx_interval);
20865   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20866   vec_free (sys_name);
20867
20868   S (mp);
20869   W (ret);
20870   return ret;
20871 }
20872
20873 static int
20874 api_sw_interface_set_lldp (vat_main_t * vam)
20875 {
20876   unformat_input_t *i = vam->input;
20877   vl_api_sw_interface_set_lldp_t *mp;
20878   u32 sw_if_index = ~0;
20879   u32 enable = 1;
20880   u8 *port_desc = NULL, *mgmt_oid = NULL;
20881   ip4_address_t ip4_addr;
20882   ip6_address_t ip6_addr;
20883   int ret;
20884
20885   memset (&ip4_addr, 0, sizeof (ip4_addr));
20886   memset (&ip6_addr, 0, sizeof (ip6_addr));
20887
20888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20889     {
20890       if (unformat (i, "disable"))
20891         enable = 0;
20892       else
20893         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20894         ;
20895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20896         ;
20897       else if (unformat (i, "port-desc %s", &port_desc))
20898         ;
20899       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20900         ;
20901       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20902         ;
20903       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20904         ;
20905       else
20906         break;
20907     }
20908
20909   if (sw_if_index == ~0)
20910     {
20911       errmsg ("missing interface name or sw_if_index");
20912       return -99;
20913     }
20914
20915   /* Construct the API message */
20916   vec_add1 (port_desc, 0);
20917   vec_add1 (mgmt_oid, 0);
20918   M (SW_INTERFACE_SET_LLDP, mp);
20919   mp->sw_if_index = ntohl (sw_if_index);
20920   mp->enable = enable;
20921   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20922   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20923   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20924   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20925   vec_free (port_desc);
20926   vec_free (mgmt_oid);
20927
20928   S (mp);
20929   W (ret);
20930   return ret;
20931 }
20932
20933 static int
20934 api_tcp_configure_src_addresses (vat_main_t * vam)
20935 {
20936   vl_api_tcp_configure_src_addresses_t *mp;
20937   unformat_input_t *i = vam->input;
20938   ip4_address_t v4first, v4last;
20939   ip6_address_t v6first, v6last;
20940   u8 range_set = 0;
20941   u32 vrf_id = 0;
20942   int ret;
20943
20944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20945     {
20946       if (unformat (i, "%U - %U",
20947                     unformat_ip4_address, &v4first,
20948                     unformat_ip4_address, &v4last))
20949         {
20950           if (range_set)
20951             {
20952               errmsg ("one range per message (range already set)");
20953               return -99;
20954             }
20955           range_set = 1;
20956         }
20957       else if (unformat (i, "%U - %U",
20958                          unformat_ip6_address, &v6first,
20959                          unformat_ip6_address, &v6last))
20960         {
20961           if (range_set)
20962             {
20963               errmsg ("one range per message (range already set)");
20964               return -99;
20965             }
20966           range_set = 2;
20967         }
20968       else if (unformat (i, "vrf %d", &vrf_id))
20969         ;
20970       else
20971         break;
20972     }
20973
20974   if (range_set == 0)
20975     {
20976       errmsg ("address range not set");
20977       return -99;
20978     }
20979
20980   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20981   mp->vrf_id = ntohl (vrf_id);
20982   /* ipv6? */
20983   if (range_set == 2)
20984     {
20985       mp->is_ipv6 = 1;
20986       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20987       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20988     }
20989   else
20990     {
20991       mp->is_ipv6 = 0;
20992       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20993       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20994     }
20995   S (mp);
20996   W (ret);
20997   return ret;
20998 }
20999
21000 static int
21001 api_app_namespace_add_del (vat_main_t * vam)
21002 {
21003   vl_api_app_namespace_add_del_t *mp;
21004   unformat_input_t *i = vam->input;
21005   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21006   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21007   u64 secret;
21008   int ret;
21009
21010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21011     {
21012       if (unformat (i, "id %_%v%_", &ns_id))
21013         ;
21014       else if (unformat (i, "secret %lu", &secret))
21015         secret_set = 1;
21016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21017         sw_if_index_set = 1;
21018       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21019         ;
21020       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21021         ;
21022       else
21023         break;
21024     }
21025   if (!ns_id || !secret_set || !sw_if_index_set)
21026     {
21027       errmsg ("namespace id, secret and sw_if_index must be set");
21028       return -99;
21029     }
21030   if (vec_len (ns_id) > 64)
21031     {
21032       errmsg ("namespace id too long");
21033       return -99;
21034     }
21035   M (APP_NAMESPACE_ADD_DEL, mp);
21036
21037   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21038   mp->namespace_id_len = vec_len (ns_id);
21039   mp->secret = clib_host_to_net_u64 (secret);
21040   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21041   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21042   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21043   vec_free (ns_id);
21044   S (mp);
21045   W (ret);
21046   return ret;
21047 }
21048
21049 static int
21050 api_memfd_segment_create (vat_main_t * vam)
21051 {
21052 #if VPP_API_TEST_BUILTIN == 0
21053   unformat_input_t *i = vam->input;
21054   vl_api_memfd_segment_create_t *mp;
21055   u64 size = 64 << 20;
21056   int ret;
21057
21058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21059     {
21060       if (unformat (i, "size %U", unformat_memory_size, &size))
21061         ;
21062       else
21063         break;
21064     }
21065
21066   M (MEMFD_SEGMENT_CREATE, mp);
21067   mp->requested_size = size;
21068   S (mp);
21069   W (ret);
21070   return ret;
21071
21072 #else
21073   errmsg ("memfd_segment_create (builtin) not supported");
21074   return -99;
21075 #endif
21076 }
21077
21078 static int
21079 api_dns_enable_disable (vat_main_t * vam)
21080 {
21081   unformat_input_t *line_input = vam->input;
21082   vl_api_dns_enable_disable_t *mp;
21083   u8 enable_disable = 1;
21084   int ret;
21085
21086   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21087     {
21088       if (unformat (line_input, "disable"))
21089         enable_disable = 0;
21090       if (unformat (line_input, "enable"))
21091         enable_disable = 1;
21092       else
21093         break;
21094     }
21095
21096   /* Construct the API message */
21097   M (DNS_ENABLE_DISABLE, mp);
21098   mp->enable = enable_disable;
21099
21100   /* send it... */
21101   S (mp);
21102   /* Wait for the reply */
21103   W (ret);
21104   return ret;
21105 }
21106
21107 static int
21108 api_dns_resolve_name (vat_main_t * vam)
21109 {
21110   unformat_input_t *line_input = vam->input;
21111   vl_api_dns_resolve_name_t *mp;
21112   u8 *name = 0;
21113   int ret;
21114
21115   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21116     {
21117       if (unformat (line_input, "%s", &name))
21118         ;
21119       else
21120         break;
21121     }
21122
21123   if (vec_len (name) > 127)
21124     {
21125       errmsg ("name too long");
21126       return -99;
21127     }
21128
21129   /* Construct the API message */
21130   M (DNS_RESOLVE_NAME, mp);
21131   memcpy (mp->name, name, vec_len (name));
21132   vec_free (name);
21133
21134   /* send it... */
21135   S (mp);
21136   /* Wait for the reply */
21137   W (ret);
21138   return ret;
21139 }
21140
21141 static int
21142 api_dns_resolve_ip (vat_main_t * vam)
21143 {
21144   unformat_input_t *line_input = vam->input;
21145   vl_api_dns_resolve_ip_t *mp;
21146   int is_ip6 = -1;
21147   ip4_address_t addr4;
21148   ip6_address_t addr6;
21149   int ret;
21150
21151   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21152     {
21153       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21154         is_ip6 = 1;
21155       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21156         is_ip6 = 0;
21157       else
21158         break;
21159     }
21160
21161   if (is_ip6 == -1)
21162     {
21163       errmsg ("missing address");
21164       return -99;
21165     }
21166
21167   /* Construct the API message */
21168   M (DNS_RESOLVE_IP, mp);
21169   mp->is_ip6 = is_ip6;
21170   if (is_ip6)
21171     memcpy (mp->address, &addr6, sizeof (addr6));
21172   else
21173     memcpy (mp->address, &addr4, sizeof (addr4));
21174
21175   /* send it... */
21176   S (mp);
21177   /* Wait for the reply */
21178   W (ret);
21179   return ret;
21180 }
21181
21182 static int
21183 api_dns_name_server_add_del (vat_main_t * vam)
21184 {
21185   unformat_input_t *i = vam->input;
21186   vl_api_dns_name_server_add_del_t *mp;
21187   u8 is_add = 1;
21188   ip6_address_t ip6_server;
21189   ip4_address_t ip4_server;
21190   int ip6_set = 0;
21191   int ip4_set = 0;
21192   int ret = 0;
21193
21194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21195     {
21196       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21197         ip6_set = 1;
21198       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21199         ip4_set = 1;
21200       else if (unformat (i, "del"))
21201         is_add = 0;
21202       else
21203         {
21204           clib_warning ("parse error '%U'", format_unformat_error, i);
21205           return -99;
21206         }
21207     }
21208
21209   if (ip4_set && ip6_set)
21210     {
21211       errmsg ("Only one server address allowed per message");
21212       return -99;
21213     }
21214   if ((ip4_set + ip6_set) == 0)
21215     {
21216       errmsg ("Server address required");
21217       return -99;
21218     }
21219
21220   /* Construct the API message */
21221   M (DNS_NAME_SERVER_ADD_DEL, mp);
21222
21223   if (ip6_set)
21224     {
21225       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21226       mp->is_ip6 = 1;
21227     }
21228   else
21229     {
21230       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21231       mp->is_ip6 = 0;
21232     }
21233
21234   mp->is_add = is_add;
21235
21236   /* send it... */
21237   S (mp);
21238
21239   /* Wait for a reply, return good/bad news  */
21240   W (ret);
21241   return ret;
21242 }
21243
21244 static int
21245 api_session_rule_add_del (vat_main_t * vam)
21246 {
21247   vl_api_session_rule_add_del_t *mp;
21248   unformat_input_t *i = vam->input;
21249   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21250   u32 appns_index = 0, scope = 0;
21251   ip4_address_t lcl_ip4, rmt_ip4;
21252   ip6_address_t lcl_ip6, rmt_ip6;
21253   u8 is_ip4 = 1, conn_set = 0;
21254   u8 is_add = 1;
21255   int ret;
21256
21257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21258     {
21259       if (unformat (i, "del"))
21260         is_add = 0;
21261       else if (unformat (i, "add"))
21262         ;
21263       else if (unformat (i, "proto tcp"))
21264         proto = 0;
21265       else if (unformat (i, "proto udp"))
21266         proto = 1;
21267       else if (unformat (i, "appns %d", &appns_index))
21268         ;
21269       else if (unformat (i, "scope %d", &scope))
21270         ;
21271       else
21272         if (unformat
21273             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21274              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21275              &rmt_port))
21276         {
21277           is_ip4 = 1;
21278           conn_set = 1;
21279         }
21280       else
21281         if (unformat
21282             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21283              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21284              &rmt_port))
21285         {
21286           is_ip4 = 0;
21287           conn_set = 1;
21288         }
21289       else if (unformat (i, "action %d", &action))
21290         ;
21291       else
21292         break;
21293     }
21294   if (proto == ~0 || !conn_set || action == ~0)
21295     {
21296       errmsg ("transport proto, connection and action must be set");
21297       return -99;
21298     }
21299
21300   if (scope > 3)
21301     {
21302       errmsg ("scope should be 0-3");
21303       return -99;
21304     }
21305
21306   M (SESSION_RULE_ADD_DEL, mp);
21307
21308   mp->is_ip4 = is_ip4;
21309   mp->transport_proto = proto;
21310   mp->lcl_plen = clib_host_to_net_u16 (lcl_plen);
21311   mp->rmt_plen = clib_host_to_net_u16 (rmt_plen);
21312   mp->action_index = clib_host_to_net_u32 (action);
21313   mp->appns_index = clib_host_to_net_u32 (appns_index);
21314   mp->scope = scope;
21315   mp->is_add = is_add;
21316   if (is_ip4)
21317     {
21318       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21319       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21320     }
21321   else
21322     {
21323       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21324       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21325     }
21326
21327   S (mp);
21328   W (ret);
21329   return ret;
21330 }
21331
21332 static int
21333 q_or_quit (vat_main_t * vam)
21334 {
21335 #if VPP_API_TEST_BUILTIN == 0
21336   longjmp (vam->jump_buf, 1);
21337 #endif
21338   return 0;                     /* not so much */
21339 }
21340
21341 static int
21342 q (vat_main_t * vam)
21343 {
21344   return q_or_quit (vam);
21345 }
21346
21347 static int
21348 quit (vat_main_t * vam)
21349 {
21350   return q_or_quit (vam);
21351 }
21352
21353 static int
21354 comment (vat_main_t * vam)
21355 {
21356   return 0;
21357 }
21358
21359 static int
21360 cmd_cmp (void *a1, void *a2)
21361 {
21362   u8 **c1 = a1;
21363   u8 **c2 = a2;
21364
21365   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21366 }
21367
21368 static int
21369 help (vat_main_t * vam)
21370 {
21371   u8 **cmds = 0;
21372   u8 *name = 0;
21373   hash_pair_t *p;
21374   unformat_input_t *i = vam->input;
21375   int j;
21376
21377   if (unformat (i, "%s", &name))
21378     {
21379       uword *hs;
21380
21381       vec_add1 (name, 0);
21382
21383       hs = hash_get_mem (vam->help_by_name, name);
21384       if (hs)
21385         print (vam->ofp, "usage: %s %s", name, hs[0]);
21386       else
21387         print (vam->ofp, "No such msg / command '%s'", name);
21388       vec_free (name);
21389       return 0;
21390     }
21391
21392   print (vam->ofp, "Help is available for the following:");
21393
21394     /* *INDENT-OFF* */
21395     hash_foreach_pair (p, vam->function_by_name,
21396     ({
21397       vec_add1 (cmds, (u8 *)(p->key));
21398     }));
21399     /* *INDENT-ON* */
21400
21401   vec_sort_with_function (cmds, cmd_cmp);
21402
21403   for (j = 0; j < vec_len (cmds); j++)
21404     print (vam->ofp, "%s", cmds[j]);
21405
21406   vec_free (cmds);
21407   return 0;
21408 }
21409
21410 static int
21411 set (vat_main_t * vam)
21412 {
21413   u8 *name = 0, *value = 0;
21414   unformat_input_t *i = vam->input;
21415
21416   if (unformat (i, "%s", &name))
21417     {
21418       /* The input buffer is a vector, not a string. */
21419       value = vec_dup (i->buffer);
21420       vec_delete (value, i->index, 0);
21421       /* Almost certainly has a trailing newline */
21422       if (value[vec_len (value) - 1] == '\n')
21423         value[vec_len (value) - 1] = 0;
21424       /* Make sure it's a proper string, one way or the other */
21425       vec_add1 (value, 0);
21426       (void) clib_macro_set_value (&vam->macro_main,
21427                                    (char *) name, (char *) value);
21428     }
21429   else
21430     errmsg ("usage: set <name> <value>");
21431
21432   vec_free (name);
21433   vec_free (value);
21434   return 0;
21435 }
21436
21437 static int
21438 unset (vat_main_t * vam)
21439 {
21440   u8 *name = 0;
21441
21442   if (unformat (vam->input, "%s", &name))
21443     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21444       errmsg ("unset: %s wasn't set", name);
21445   vec_free (name);
21446   return 0;
21447 }
21448
21449 typedef struct
21450 {
21451   u8 *name;
21452   u8 *value;
21453 } macro_sort_t;
21454
21455
21456 static int
21457 macro_sort_cmp (void *a1, void *a2)
21458 {
21459   macro_sort_t *s1 = a1;
21460   macro_sort_t *s2 = a2;
21461
21462   return strcmp ((char *) (s1->name), (char *) (s2->name));
21463 }
21464
21465 static int
21466 dump_macro_table (vat_main_t * vam)
21467 {
21468   macro_sort_t *sort_me = 0, *sm;
21469   int i;
21470   hash_pair_t *p;
21471
21472     /* *INDENT-OFF* */
21473     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21474     ({
21475       vec_add2 (sort_me, sm, 1);
21476       sm->name = (u8 *)(p->key);
21477       sm->value = (u8 *) (p->value[0]);
21478     }));
21479     /* *INDENT-ON* */
21480
21481   vec_sort_with_function (sort_me, macro_sort_cmp);
21482
21483   if (vec_len (sort_me))
21484     print (vam->ofp, "%-15s%s", "Name", "Value");
21485   else
21486     print (vam->ofp, "The macro table is empty...");
21487
21488   for (i = 0; i < vec_len (sort_me); i++)
21489     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21490   return 0;
21491 }
21492
21493 static int
21494 dump_node_table (vat_main_t * vam)
21495 {
21496   int i, j;
21497   vlib_node_t *node, *next_node;
21498
21499   if (vec_len (vam->graph_nodes) == 0)
21500     {
21501       print (vam->ofp, "Node table empty, issue get_node_graph...");
21502       return 0;
21503     }
21504
21505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21506     {
21507       node = vam->graph_nodes[i];
21508       print (vam->ofp, "[%d] %s", i, node->name);
21509       for (j = 0; j < vec_len (node->next_nodes); j++)
21510         {
21511           if (node->next_nodes[j] != ~0)
21512             {
21513               next_node = vam->graph_nodes[node->next_nodes[j]];
21514               print (vam->ofp, "  [%d] %s", j, next_node->name);
21515             }
21516         }
21517     }
21518   return 0;
21519 }
21520
21521 static int
21522 value_sort_cmp (void *a1, void *a2)
21523 {
21524   name_sort_t *n1 = a1;
21525   name_sort_t *n2 = a2;
21526
21527   if (n1->value < n2->value)
21528     return -1;
21529   if (n1->value > n2->value)
21530     return 1;
21531   return 0;
21532 }
21533
21534
21535 static int
21536 dump_msg_api_table (vat_main_t * vam)
21537 {
21538   api_main_t *am = &api_main;
21539   name_sort_t *nses = 0, *ns;
21540   hash_pair_t *hp;
21541   int i;
21542
21543   /* *INDENT-OFF* */
21544   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21545   ({
21546     vec_add2 (nses, ns, 1);
21547     ns->name = (u8 *)(hp->key);
21548     ns->value = (u32) hp->value[0];
21549   }));
21550   /* *INDENT-ON* */
21551
21552   vec_sort_with_function (nses, value_sort_cmp);
21553
21554   for (i = 0; i < vec_len (nses); i++)
21555     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21556   vec_free (nses);
21557   return 0;
21558 }
21559
21560 static int
21561 get_msg_id (vat_main_t * vam)
21562 {
21563   u8 *name_and_crc;
21564   u32 message_index;
21565
21566   if (unformat (vam->input, "%s", &name_and_crc))
21567     {
21568       message_index = vl_api_get_msg_index (name_and_crc);
21569       if (message_index == ~0)
21570         {
21571           print (vam->ofp, " '%s' not found", name_and_crc);
21572           return 0;
21573         }
21574       print (vam->ofp, " '%s' has message index %d",
21575              name_and_crc, message_index);
21576       return 0;
21577     }
21578   errmsg ("name_and_crc required...");
21579   return 0;
21580 }
21581
21582 static int
21583 search_node_table (vat_main_t * vam)
21584 {
21585   unformat_input_t *line_input = vam->input;
21586   u8 *node_to_find;
21587   int j;
21588   vlib_node_t *node, *next_node;
21589   uword *p;
21590
21591   if (vam->graph_node_index_by_name == 0)
21592     {
21593       print (vam->ofp, "Node table empty, issue get_node_graph...");
21594       return 0;
21595     }
21596
21597   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21598     {
21599       if (unformat (line_input, "%s", &node_to_find))
21600         {
21601           vec_add1 (node_to_find, 0);
21602           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21603           if (p == 0)
21604             {
21605               print (vam->ofp, "%s not found...", node_to_find);
21606               goto out;
21607             }
21608           node = vam->graph_nodes[p[0]];
21609           print (vam->ofp, "[%d] %s", p[0], node->name);
21610           for (j = 0; j < vec_len (node->next_nodes); j++)
21611             {
21612               if (node->next_nodes[j] != ~0)
21613                 {
21614                   next_node = vam->graph_nodes[node->next_nodes[j]];
21615                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21616                 }
21617             }
21618         }
21619
21620       else
21621         {
21622           clib_warning ("parse error '%U'", format_unformat_error,
21623                         line_input);
21624           return -99;
21625         }
21626
21627     out:
21628       vec_free (node_to_find);
21629
21630     }
21631
21632   return 0;
21633 }
21634
21635
21636 static int
21637 script (vat_main_t * vam)
21638 {
21639 #if (VPP_API_TEST_BUILTIN==0)
21640   u8 *s = 0;
21641   char *save_current_file;
21642   unformat_input_t save_input;
21643   jmp_buf save_jump_buf;
21644   u32 save_line_number;
21645
21646   FILE *new_fp, *save_ifp;
21647
21648   if (unformat (vam->input, "%s", &s))
21649     {
21650       new_fp = fopen ((char *) s, "r");
21651       if (new_fp == 0)
21652         {
21653           errmsg ("Couldn't open script file %s", s);
21654           vec_free (s);
21655           return -99;
21656         }
21657     }
21658   else
21659     {
21660       errmsg ("Missing script name");
21661       return -99;
21662     }
21663
21664   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21665   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21666   save_ifp = vam->ifp;
21667   save_line_number = vam->input_line_number;
21668   save_current_file = (char *) vam->current_file;
21669
21670   vam->input_line_number = 0;
21671   vam->ifp = new_fp;
21672   vam->current_file = s;
21673   do_one_file (vam);
21674
21675   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21676   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21677   vam->ifp = save_ifp;
21678   vam->input_line_number = save_line_number;
21679   vam->current_file = (u8 *) save_current_file;
21680   vec_free (s);
21681
21682   return 0;
21683 #else
21684   clib_warning ("use the exec command...");
21685   return -99;
21686 #endif
21687 }
21688
21689 static int
21690 echo (vat_main_t * vam)
21691 {
21692   print (vam->ofp, "%v", vam->input->buffer);
21693   return 0;
21694 }
21695
21696 /* List of API message constructors, CLI names map to api_xxx */
21697 #define foreach_vpe_api_msg                                             \
21698 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21699 _(sw_interface_dump,"")                                                 \
21700 _(sw_interface_set_flags,                                               \
21701   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21702 _(sw_interface_add_del_address,                                         \
21703   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21704 _(sw_interface_set_rx_mode,                                             \
21705   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21706 _(sw_interface_set_table,                                               \
21707   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21708 _(sw_interface_set_mpls_enable,                                         \
21709   "<intfc> | sw_if_index [disable | dis]")                              \
21710 _(sw_interface_set_vpath,                                               \
21711   "<intfc> | sw_if_index <id> enable | disable")                        \
21712 _(sw_interface_set_vxlan_bypass,                                        \
21713   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21714 _(sw_interface_set_geneve_bypass,                                       \
21715   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21716 _(sw_interface_set_l2_xconnect,                                         \
21717   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21718   "enable | disable")                                                   \
21719 _(sw_interface_set_l2_bridge,                                           \
21720   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21721   "[shg <split-horizon-group>] [bvi]\n"                                 \
21722   "enable | disable")                                                   \
21723 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21724 _(bridge_domain_add_del,                                                \
21725   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [bd-tag <tag>] [del]\n") \
21726 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21727 _(l2fib_add_del,                                                        \
21728   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21729 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21730 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21731 _(l2_flags,                                                             \
21732   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21733 _(bridge_flags,                                                         \
21734   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21735 _(tap_connect,                                                          \
21736   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21737 _(tap_modify,                                                           \
21738   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21739 _(tap_delete,                                                           \
21740   "<vpp-if-name> | sw_if_index <id>")                                   \
21741 _(sw_interface_tap_dump, "")                                            \
21742 _(ip_table_add_del,                                                     \
21743   "table-id <n> [ipv6]\n")                                              \
21744 _(ip_add_del_route,                                                     \
21745   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21746   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21747   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21748   "[multipath] [count <n>]")                                            \
21749 _(ip_mroute_add_del,                                                    \
21750   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21751   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21752 _(mpls_table_add_del,                                                   \
21753   "table-id <n>\n")                                                     \
21754 _(mpls_route_add_del,                                                   \
21755   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21756   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21757   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21758   "[multipath] [count <n>]")                                            \
21759 _(mpls_ip_bind_unbind,                                                  \
21760   "<label> <addr/len>")                                                 \
21761 _(mpls_tunnel_add_del,                                                  \
21762   " via <addr> [table-id <n>]\n"                                        \
21763   "sw_if_index <id>] [l2]  [del]")                                      \
21764 _(proxy_arp_add_del,                                                    \
21765   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21766 _(proxy_arp_intfc_enable_disable,                                       \
21767   "<intfc> | sw_if_index <id> enable | disable")                        \
21768 _(sw_interface_set_unnumbered,                                          \
21769   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21770 _(ip_neighbor_add_del,                                                  \
21771   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21772   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21773 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21774 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21775 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21776   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21777   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21778   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21779 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21780 _(reset_fib, "vrf <n> [ipv6]")                                          \
21781 _(dhcp_proxy_config,                                                    \
21782   "svr <v46-address> src <v46-address>\n"                               \
21783    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21784 _(dhcp_proxy_set_vss,                                                   \
21785   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21786 _(dhcp_proxy_dump, "ip6")                                               \
21787 _(dhcp_client_config,                                                   \
21788   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21789 _(set_ip_flow_hash,                                                     \
21790   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21791 _(sw_interface_ip6_enable_disable,                                      \
21792   "<intfc> | sw_if_index <id> enable | disable")                        \
21793 _(sw_interface_ip6_set_link_local_address,                              \
21794   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21795 _(ip6nd_proxy_add_del,                                                  \
21796   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21797 _(ip6nd_proxy_dump, "")                                                 \
21798 _(sw_interface_ip6nd_ra_prefix,                                         \
21799   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21800   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21801   "[nolink] [isno]")                                                    \
21802 _(sw_interface_ip6nd_ra_config,                                         \
21803   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21804   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21805   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21806 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21807 _(l2_patch_add_del,                                                     \
21808   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21809   "enable | disable")                                                   \
21810 _(sr_localsid_add_del,                                                  \
21811   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21812   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21813 _(classify_add_del_table,                                               \
21814   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21815   " [del] [del-chain] mask <mask-value>\n"                              \
21816   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21817   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21818 _(classify_add_del_session,                                             \
21819   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21820   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21821   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21822   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21823 _(classify_set_interface_ip_table,                                      \
21824   "<intfc> | sw_if_index <nn> table <nn>")                              \
21825 _(classify_set_interface_l2_tables,                                     \
21826   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21827   "  [other-table <nn>]")                                               \
21828 _(get_node_index, "node <node-name")                                    \
21829 _(add_node_next, "node <node-name> next <next-node-name>")              \
21830 _(l2tpv3_create_tunnel,                                                 \
21831   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21832   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21833   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21834 _(l2tpv3_set_tunnel_cookies,                                            \
21835   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21836   "[new_remote_cookie <nn>]\n")                                         \
21837 _(l2tpv3_interface_enable_disable,                                      \
21838   "<intfc> | sw_if_index <nn> enable | disable")                        \
21839 _(l2tpv3_set_lookup_key,                                                \
21840   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21841 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21842 _(vxlan_add_del_tunnel,                                                 \
21843   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21844   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21845   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21846 _(geneve_add_del_tunnel,                                                \
21847   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21848   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21849   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21850 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21851 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21852 _(gre_add_del_tunnel,                                                   \
21853   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21854 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21855 _(l2_fib_clear_table, "")                                               \
21856 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21857 _(l2_interface_vlan_tag_rewrite,                                        \
21858   "<intfc> | sw_if_index <nn> \n"                                       \
21859   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21860   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21861 _(create_vhost_user_if,                                                 \
21862         "socket <filename> [server] [renumber <dev_instance>] "         \
21863         "[mac <mac_address>]")                                          \
21864 _(modify_vhost_user_if,                                                 \
21865         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21866         "[server] [renumber <dev_instance>]")                           \
21867 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21868 _(sw_interface_vhost_user_dump, "")                                     \
21869 _(show_version, "")                                                     \
21870 _(vxlan_gpe_add_del_tunnel,                                             \
21871   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21872   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21873   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21874   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21875 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21876 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21877 _(interface_name_renumber,                                              \
21878   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21879 _(input_acl_set_interface,                                              \
21880   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21881   "  [l2-table <nn>] [del]")                                            \
21882 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21883 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21884 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21885 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21886 _(ip_dump, "ipv4 | ipv6")                                               \
21887 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21888 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21889   "  spid_id <n> ")                                                     \
21890 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21891   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21892   "  integ_alg <alg> integ_key <hex>")                                  \
21893 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21894   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21895   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21896   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21897 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21898 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21899   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21900   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21901   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21902 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21903 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21904   "  <alg> <hex>\n")                                                    \
21905 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21906 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21907 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21908   "(auth_data 0x<data> | auth_data <data>)")                            \
21909 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21910   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21911 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21912   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21913   "(local|remote)")                                                     \
21914 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21915 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21916 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21917 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21918 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21919 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21920 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21921 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21922 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21923 _(delete_loopback,"sw_if_index <nn>")                                   \
21924 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21925 _(map_add_domain,                                                       \
21926   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21927   "ip6-src <ip6addr> "                                                  \
21928   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21929 _(map_del_domain, "index <n>")                                          \
21930 _(map_add_del_rule,                                                     \
21931   "index <n> psid <n> dst <ip6addr> [del]")                             \
21932 _(map_domain_dump, "")                                                  \
21933 _(map_rule_dump, "index <map-domain>")                                  \
21934 _(want_interface_events,  "enable|disable")                             \
21935 _(want_stats,"enable|disable")                                          \
21936 _(get_first_msg_id, "client <name>")                                    \
21937 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21938 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21939   "fib-id <nn> [ip4][ip6][default]")                                    \
21940 _(get_node_graph, " ")                                                  \
21941 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21942 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21943 _(ioam_disable, "")                                                     \
21944 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21945                             " sw_if_index <sw_if_index> p <priority> "  \
21946                             "w <weight>] [del]")                        \
21947 _(one_add_del_locator, "locator-set <locator_name> "                    \
21948                         "iface <intf> | sw_if_index <sw_if_index> "     \
21949                         "p <priority> w <weight> [del]")                \
21950 _(one_add_del_local_eid,"vni <vni> eid "                                \
21951                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21952                          "locator-set <locator_name> [del]"             \
21953                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21954 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21955 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21956 _(one_enable_disable, "enable|disable")                                 \
21957 _(one_map_register_enable_disable, "enable|disable")                    \
21958 _(one_map_register_fallback_threshold, "<value>")                       \
21959 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21960 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21961                                "[seid <seid>] "                         \
21962                                "rloc <locator> p <prio> "               \
21963                                "w <weight> [rloc <loc> ... ] "          \
21964                                "action <action> [del-all]")             \
21965 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21966                           "<local-eid>")                                \
21967 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21968 _(one_use_petr, "ip-address> | disable")                                \
21969 _(one_map_request_mode, "src-dst|dst-only")                             \
21970 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21971 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21972 _(one_locator_set_dump, "[local | remote]")                             \
21973 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21974 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21975                        "[local] | [remote]")                            \
21976 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21977 _(one_ndp_bd_get, "")                                                   \
21978 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21979 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21980 _(one_l2_arp_bd_get, "")                                                \
21981 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21982 _(one_stats_enable_disable, "enable|disalbe")                           \
21983 _(show_one_stats_enable_disable, "")                                    \
21984 _(one_eid_table_vni_dump, "")                                           \
21985 _(one_eid_table_map_dump, "l2|l3")                                      \
21986 _(one_map_resolver_dump, "")                                            \
21987 _(one_map_server_dump, "")                                              \
21988 _(one_adjacencies_get, "vni <vni>")                                     \
21989 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21990 _(show_one_rloc_probe_state, "")                                        \
21991 _(show_one_map_register_state, "")                                      \
21992 _(show_one_status, "")                                                  \
21993 _(one_stats_dump, "")                                                   \
21994 _(one_stats_flush, "")                                                  \
21995 _(one_get_map_request_itr_rlocs, "")                                    \
21996 _(one_map_register_set_ttl, "<ttl>")                                    \
21997 _(one_set_transport_protocol, "udp|api")                                \
21998 _(one_get_transport_protocol, "")                                       \
21999 _(show_one_nsh_mapping, "")                                             \
22000 _(show_one_pitr, "")                                                    \
22001 _(show_one_use_petr, "")                                                \
22002 _(show_one_map_request_mode, "")                                        \
22003 _(show_one_map_register_ttl, "")                                        \
22004 _(show_one_map_register_fallback_threshold, "")                         \
22005 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22006                             " sw_if_index <sw_if_index> p <priority> "  \
22007                             "w <weight>] [del]")                        \
22008 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22009                         "iface <intf> | sw_if_index <sw_if_index> "     \
22010                         "p <priority> w <weight> [del]")                \
22011 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22012                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22013                          "locator-set <locator_name> [del]"             \
22014                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22015 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22016 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22017 _(lisp_enable_disable, "enable|disable")                                \
22018 _(lisp_map_register_enable_disable, "enable|disable")                   \
22019 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22020 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22021                                "[seid <seid>] "                         \
22022                                "rloc <locator> p <prio> "               \
22023                                "w <weight> [rloc <loc> ... ] "          \
22024                                "action <action> [del-all]")             \
22025 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22026                           "<local-eid>")                                \
22027 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22028 _(lisp_use_petr, "<ip-address> | disable")                              \
22029 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22030 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22031 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22032 _(lisp_locator_set_dump, "[local | remote]")                            \
22033 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22034 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22035                        "[local] | [remote]")                            \
22036 _(lisp_eid_table_vni_dump, "")                                          \
22037 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22038 _(lisp_map_resolver_dump, "")                                           \
22039 _(lisp_map_server_dump, "")                                             \
22040 _(lisp_adjacencies_get, "vni <vni>")                                    \
22041 _(gpe_fwd_entry_vnis_get, "")                                           \
22042 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22043 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22044                                 "[table <table-id>]")                   \
22045 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22046 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22047 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22048 _(gpe_get_encap_mode, "")                                               \
22049 _(lisp_gpe_add_del_iface, "up|down")                                    \
22050 _(lisp_gpe_enable_disable, "enable|disable")                            \
22051 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22052   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22053 _(show_lisp_rloc_probe_state, "")                                       \
22054 _(show_lisp_map_register_state, "")                                     \
22055 _(show_lisp_status, "")                                                 \
22056 _(lisp_get_map_request_itr_rlocs, "")                                   \
22057 _(show_lisp_pitr, "")                                                   \
22058 _(show_lisp_use_petr, "")                                               \
22059 _(show_lisp_map_request_mode, "")                                       \
22060 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22061 _(af_packet_delete, "name <host interface name>")                       \
22062 _(policer_add_del, "name <policer name> <params> [del]")                \
22063 _(policer_dump, "[name <policer name>]")                                \
22064 _(policer_classify_set_interface,                                       \
22065   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22066   "  [l2-table <nn>] [del]")                                            \
22067 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22068 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22069     "[master|slave]")                                                   \
22070 _(netmap_delete, "name <interface name>")                               \
22071 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22072 _(mpls_fib_dump, "")                                                    \
22073 _(classify_table_ids, "")                                               \
22074 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22075 _(classify_table_info, "table_id <nn>")                                 \
22076 _(classify_session_dump, "table_id <nn>")                               \
22077 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22078     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22079     "[template_interval <nn>] [udp_checksum]")                          \
22080 _(ipfix_exporter_dump, "")                                              \
22081 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22082 _(ipfix_classify_stream_dump, "")                                       \
22083 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22084 _(ipfix_classify_table_dump, "")                                        \
22085 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22086 _(sw_interface_span_dump, "[l2]")                                           \
22087 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22088 _(pg_create_interface, "if_id <nn>")                                    \
22089 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22090 _(pg_enable_disable, "[stream <id>] disable")                           \
22091 _(ip_source_and_port_range_check_add_del,                               \
22092   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22093 _(ip_source_and_port_range_check_interface_add_del,                     \
22094   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22095   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22096 _(ipsec_gre_add_del_tunnel,                                             \
22097   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22098 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22099 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22100 _(l2_interface_pbb_tag_rewrite,                                         \
22101   "<intfc> | sw_if_index <nn> \n"                                       \
22102   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22103   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22104 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22105 _(flow_classify_set_interface,                                          \
22106   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22107 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22108 _(ip_fib_dump, "")                                                      \
22109 _(ip_mfib_dump, "")                                                     \
22110 _(ip6_fib_dump, "")                                                     \
22111 _(ip6_mfib_dump, "")                                                    \
22112 _(feature_enable_disable, "arc_name <arc_name> "                        \
22113   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22114 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22115 "[disable]")                                                            \
22116 _(l2_xconnect_dump, "")                                                 \
22117 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22118 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22119 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22120 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22121 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22122 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22123 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22124   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22125 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22126 _(memfd_segment_create,"size <nnn>")                                    \
22127 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22128 _(dns_enable_disable, "[enable][disable]")                              \
22129 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22130 _(dns_resolve_name, "<hostname>")                                       \
22131 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22132 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22133 _(dns_resolve_name, "<hostname>")                                       \
22134 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22135   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22136
22137 /* List of command functions, CLI names map directly to functions */
22138 #define foreach_cli_function                                    \
22139 _(comment, "usage: comment <ignore-rest-of-line>")              \
22140 _(dump_interface_table, "usage: dump_interface_table")          \
22141 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22142 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22143 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22144 _(dump_stats_table, "usage: dump_stats_table")                  \
22145 _(dump_macro_table, "usage: dump_macro_table ")                 \
22146 _(dump_node_table, "usage: dump_node_table")                    \
22147 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22148 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22149 _(echo, "usage: echo <message>")                                \
22150 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22151 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22152 _(help, "usage: help")                                          \
22153 _(q, "usage: quit")                                             \
22154 _(quit, "usage: quit")                                          \
22155 _(search_node_table, "usage: search_node_table <name>...")      \
22156 _(set, "usage: set <variable-name> <value>")                    \
22157 _(script, "usage: script <file-name>")                          \
22158 _(unset, "usage: unset <variable-name>")
22159 #define _(N,n)                                  \
22160     static void vl_api_##n##_t_handler_uni      \
22161     (vl_api_##n##_t * mp)                       \
22162     {                                           \
22163         vat_main_t * vam = &vat_main;           \
22164         if (vam->json_output) {                 \
22165             vl_api_##n##_t_handler_json(mp);    \
22166         } else {                                \
22167             vl_api_##n##_t_handler(mp);         \
22168         }                                       \
22169     }
22170 foreach_vpe_api_reply_msg;
22171 #if VPP_API_TEST_BUILTIN == 0
22172 foreach_standalone_reply_msg;
22173 #endif
22174 #undef _
22175
22176 void
22177 vat_api_hookup (vat_main_t * vam)
22178 {
22179 #define _(N,n)                                                  \
22180     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22181                            vl_api_##n##_t_handler_uni,          \
22182                            vl_noop_handler,                     \
22183                            vl_api_##n##_t_endian,               \
22184                            vl_api_##n##_t_print,                \
22185                            sizeof(vl_api_##n##_t), 1);
22186   foreach_vpe_api_reply_msg;
22187 #if VPP_API_TEST_BUILTIN == 0
22188   foreach_standalone_reply_msg;
22189 #endif
22190 #undef _
22191
22192 #if (VPP_API_TEST_BUILTIN==0)
22193   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22194
22195   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22196
22197   vam->function_by_name = hash_create_string (0, sizeof (uword));
22198
22199   vam->help_by_name = hash_create_string (0, sizeof (uword));
22200 #endif
22201
22202   /* API messages we can send */
22203 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22204   foreach_vpe_api_msg;
22205 #undef _
22206
22207   /* Help strings */
22208 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22209   foreach_vpe_api_msg;
22210 #undef _
22211
22212   /* CLI functions */
22213 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22214   foreach_cli_function;
22215 #undef _
22216
22217   /* Help strings */
22218 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22219   foreach_cli_function;
22220 #undef _
22221 }
22222
22223 #if VPP_API_TEST_BUILTIN
22224 static clib_error_t *
22225 vat_api_hookup_shim (vlib_main_t * vm)
22226 {
22227   vat_api_hookup (&vat_main);
22228   return 0;
22229 }
22230
22231 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22232 #endif
22233
22234 /*
22235  * fd.io coding-style-patch-verification: ON
22236  *
22237  * Local Variables:
22238  * eval: (c-set-style "gnu")
22239  * End:
22240  */