Break up vpe.api
[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_one_show_xtr_mode_reply_t_handler
4243   (vl_api_one_show_xtr_mode_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->is_en ? "enabled" : "disabled");
4251     }
4252
4253   vam->retval = retval;
4254   vam->result_ready = 1;
4255 }
4256
4257 static void
4258   vl_api_one_show_xtr_mode_reply_t_handler_json
4259   (vl_api_one_show_xtr_mode_reply_t * mp)
4260 {
4261   vat_main_t *vam = &vat_main;
4262   vat_json_node_t node;
4263   u8 *status = 0;
4264
4265   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4266   vec_add1 (status, 0);
4267
4268   vat_json_init_object (&node);
4269   vat_json_object_add_string_copy (&node, "status", status);
4270
4271   vec_free (status);
4272
4273   vat_json_print (vam->ofp, &node);
4274   vat_json_free (&node);
4275
4276   vam->retval = ntohl (mp->retval);
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_one_show_pitr_mode_reply_t_handler
4282   (vl_api_one_show_pitr_mode_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   i32 retval = ntohl (mp->retval);
4286
4287   if (0 <= retval)
4288     {
4289       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4290     }
4291
4292   vam->retval = retval;
4293   vam->result_ready = 1;
4294 }
4295
4296 static void
4297   vl_api_one_show_pitr_mode_reply_t_handler_json
4298   (vl_api_one_show_pitr_mode_reply_t * mp)
4299 {
4300   vat_main_t *vam = &vat_main;
4301   vat_json_node_t node;
4302   u8 *status = 0;
4303
4304   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4305   vec_add1 (status, 0);
4306
4307   vat_json_init_object (&node);
4308   vat_json_object_add_string_copy (&node, "status", status);
4309
4310   vec_free (status);
4311
4312   vat_json_print (vam->ofp, &node);
4313   vat_json_free (&node);
4314
4315   vam->retval = ntohl (mp->retval);
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_one_show_petr_mode_reply_t_handler
4321   (vl_api_one_show_petr_mode_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   i32 retval = ntohl (mp->retval);
4325
4326   if (0 <= retval)
4327     {
4328       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4329     }
4330
4331   vam->retval = retval;
4332   vam->result_ready = 1;
4333 }
4334
4335 static void
4336   vl_api_one_show_petr_mode_reply_t_handler_json
4337   (vl_api_one_show_petr_mode_reply_t * mp)
4338 {
4339   vat_main_t *vam = &vat_main;
4340   vat_json_node_t node;
4341   u8 *status = 0;
4342
4343   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4344   vec_add1 (status, 0);
4345
4346   vat_json_init_object (&node);
4347   vat_json_object_add_string_copy (&node, "status", status);
4348
4349   vec_free (status);
4350
4351   vat_json_print (vam->ofp, &node);
4352   vat_json_free (&node);
4353
4354   vam->retval = ntohl (mp->retval);
4355   vam->result_ready = 1;
4356 }
4357
4358 static void
4359   vl_api_show_one_use_petr_reply_t_handler
4360   (vl_api_show_one_use_petr_reply_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   i32 retval = ntohl (mp->retval);
4364
4365   if (0 <= retval)
4366     {
4367       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4368       if (mp->status)
4369         {
4370           print (vam->ofp, "Proxy-ETR address; %U",
4371                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4372                  mp->address);
4373         }
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_use_petr_reply_t_handler_json
4382   (vl_api_show_one_use_petr_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386   u8 *status = 0;
4387   struct in_addr ip4;
4388   struct in6_addr ip6;
4389
4390   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4391   vec_add1 (status, 0);
4392
4393   vat_json_init_object (&node);
4394   vat_json_object_add_string_copy (&node, "status", status);
4395   if (mp->status)
4396     {
4397       if (mp->is_ip4)
4398         {
4399           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4400           vat_json_object_add_ip6 (&node, "address", ip6);
4401         }
4402       else
4403         {
4404           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4405           vat_json_object_add_ip4 (&node, "address", ip4);
4406         }
4407     }
4408
4409   vec_free (status);
4410
4411   vat_json_print (vam->ofp, &node);
4412   vat_json_free (&node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419   vl_api_show_one_nsh_mapping_reply_t_handler
4420   (vl_api_show_one_nsh_mapping_reply_t * mp)
4421 {
4422   vat_main_t *vam = &vat_main;
4423   i32 retval = ntohl (mp->retval);
4424
4425   if (0 <= retval)
4426     {
4427       print (vam->ofp, "%-20s%-16s",
4428              mp->is_set ? "set" : "not-set",
4429              mp->is_set ? (char *) mp->locator_set_name : "");
4430     }
4431
4432   vam->retval = retval;
4433   vam->result_ready = 1;
4434 }
4435
4436 static void
4437   vl_api_show_one_nsh_mapping_reply_t_handler_json
4438   (vl_api_show_one_nsh_mapping_reply_t * mp)
4439 {
4440   vat_main_t *vam = &vat_main;
4441   vat_json_node_t node;
4442   u8 *status = 0;
4443
4444   status = format (0, "%s", mp->is_set ? "yes" : "no");
4445   vec_add1 (status, 0);
4446
4447   vat_json_init_object (&node);
4448   vat_json_object_add_string_copy (&node, "is_set", status);
4449   if (mp->is_set)
4450     {
4451       vat_json_object_add_string_copy (&node, "locator_set",
4452                                        mp->locator_set_name);
4453     }
4454
4455   vec_free (status);
4456
4457   vat_json_print (vam->ofp, &node);
4458   vat_json_free (&node);
4459
4460   vam->retval = ntohl (mp->retval);
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465   vl_api_show_one_map_register_ttl_reply_t_handler
4466   (vl_api_show_one_map_register_ttl_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   i32 retval = ntohl (mp->retval);
4470
4471   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "ttl: %u", mp->ttl);
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_show_one_map_register_ttl_reply_t_handler_json
4484   (vl_api_show_one_map_register_ttl_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488
4489   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4490   vat_json_init_object (&node);
4491   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4492
4493   vat_json_print (vam->ofp, &node);
4494   vat_json_free (&node);
4495
4496   vam->retval = ntohl (mp->retval);
4497   vam->result_ready = 1;
4498 }
4499
4500 static void
4501 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   i32 retval = ntohl (mp->retval);
4505
4506   if (0 <= retval)
4507     {
4508       print (vam->ofp, "%-20s%-16s",
4509              mp->status ? "enabled" : "disabled",
4510              mp->status ? (char *) mp->locator_set_name : "");
4511     }
4512
4513   vam->retval = retval;
4514   vam->result_ready = 1;
4515 }
4516
4517 static void
4518 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4519 {
4520   vat_main_t *vam = &vat_main;
4521   vat_json_node_t node;
4522   u8 *status = 0;
4523
4524   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4525   vec_add1 (status, 0);
4526
4527   vat_json_init_object (&node);
4528   vat_json_object_add_string_copy (&node, "status", status);
4529   if (mp->status)
4530     {
4531       vat_json_object_add_string_copy (&node, "locator_set",
4532                                        mp->locator_set_name);
4533     }
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static u8 *
4545 format_policer_type (u8 * s, va_list * va)
4546 {
4547   u32 i = va_arg (*va, u32);
4548
4549   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4550     s = format (s, "1r2c");
4551   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4552     s = format (s, "1r3c");
4553   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4554     s = format (s, "2r3c-2698");
4555   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4556     s = format (s, "2r3c-4115");
4557   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4558     s = format (s, "2r3c-mef5cf1");
4559   else
4560     s = format (s, "ILLEGAL");
4561   return s;
4562 }
4563
4564 static u8 *
4565 format_policer_rate_type (u8 * s, va_list * va)
4566 {
4567   u32 i = va_arg (*va, u32);
4568
4569   if (i == SSE2_QOS_RATE_KBPS)
4570     s = format (s, "kbps");
4571   else if (i == SSE2_QOS_RATE_PPS)
4572     s = format (s, "pps");
4573   else
4574     s = format (s, "ILLEGAL");
4575   return s;
4576 }
4577
4578 static u8 *
4579 format_policer_round_type (u8 * s, va_list * va)
4580 {
4581   u32 i = va_arg (*va, u32);
4582
4583   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4584     s = format (s, "closest");
4585   else if (i == SSE2_QOS_ROUND_TO_UP)
4586     s = format (s, "up");
4587   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4588     s = format (s, "down");
4589   else
4590     s = format (s, "ILLEGAL");
4591   return s;
4592 }
4593
4594 static u8 *
4595 format_policer_action_type (u8 * s, va_list * va)
4596 {
4597   u32 i = va_arg (*va, u32);
4598
4599   if (i == SSE2_QOS_ACTION_DROP)
4600     s = format (s, "drop");
4601   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4602     s = format (s, "transmit");
4603   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4604     s = format (s, "mark-and-transmit");
4605   else
4606     s = format (s, "ILLEGAL");
4607   return s;
4608 }
4609
4610 static u8 *
4611 format_dscp (u8 * s, va_list * va)
4612 {
4613   u32 i = va_arg (*va, u32);
4614   char *t = 0;
4615
4616   switch (i)
4617     {
4618 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4619       foreach_vnet_dscp
4620 #undef _
4621     default:
4622       return format (s, "ILLEGAL");
4623     }
4624   s = format (s, "%s", t);
4625   return s;
4626 }
4627
4628 static void
4629 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4630 {
4631   vat_main_t *vam = &vat_main;
4632   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4633
4634   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4635     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4636   else
4637     conform_dscp_str = format (0, "");
4638
4639   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4640     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4641   else
4642     exceed_dscp_str = format (0, "");
4643
4644   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4645     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4646   else
4647     violate_dscp_str = format (0, "");
4648
4649   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4650          "rate type %U, round type %U, %s rate, %s color-aware, "
4651          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4652          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4653          "conform action %U%s, exceed action %U%s, violate action %U%s",
4654          mp->name,
4655          format_policer_type, mp->type,
4656          ntohl (mp->cir),
4657          ntohl (mp->eir),
4658          clib_net_to_host_u64 (mp->cb),
4659          clib_net_to_host_u64 (mp->eb),
4660          format_policer_rate_type, mp->rate_type,
4661          format_policer_round_type, mp->round_type,
4662          mp->single_rate ? "single" : "dual",
4663          mp->color_aware ? "is" : "not",
4664          ntohl (mp->cir_tokens_per_period),
4665          ntohl (mp->pir_tokens_per_period),
4666          ntohl (mp->scale),
4667          ntohl (mp->current_limit),
4668          ntohl (mp->current_bucket),
4669          ntohl (mp->extended_limit),
4670          ntohl (mp->extended_bucket),
4671          clib_net_to_host_u64 (mp->last_update_time),
4672          format_policer_action_type, mp->conform_action_type,
4673          conform_dscp_str,
4674          format_policer_action_type, mp->exceed_action_type,
4675          exceed_dscp_str,
4676          format_policer_action_type, mp->violate_action_type,
4677          violate_dscp_str);
4678
4679   vec_free (conform_dscp_str);
4680   vec_free (exceed_dscp_str);
4681   vec_free (violate_dscp_str);
4682 }
4683
4684 static void vl_api_policer_details_t_handler_json
4685   (vl_api_policer_details_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   vat_json_node_t *node;
4689   u8 *rate_type_str, *round_type_str, *type_str;
4690   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4691
4692   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4693   round_type_str =
4694     format (0, "%U", format_policer_round_type, mp->round_type);
4695   type_str = format (0, "%U", format_policer_type, mp->type);
4696   conform_action_str = format (0, "%U", format_policer_action_type,
4697                                mp->conform_action_type);
4698   exceed_action_str = format (0, "%U", format_policer_action_type,
4699                               mp->exceed_action_type);
4700   violate_action_str = format (0, "%U", format_policer_action_type,
4701                                mp->violate_action_type);
4702
4703   if (VAT_JSON_ARRAY != vam->json_tree.type)
4704     {
4705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4706       vat_json_init_array (&vam->json_tree);
4707     }
4708   node = vat_json_array_add (&vam->json_tree);
4709
4710   vat_json_init_object (node);
4711   vat_json_object_add_string_copy (node, "name", mp->name);
4712   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4713   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4714   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4715   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4716   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4717   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4718   vat_json_object_add_string_copy (node, "type", type_str);
4719   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4720   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4721   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4722   vat_json_object_add_uint (node, "cir_tokens_per_period",
4723                             ntohl (mp->cir_tokens_per_period));
4724   vat_json_object_add_uint (node, "eir_tokens_per_period",
4725                             ntohl (mp->pir_tokens_per_period));
4726   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4727   vat_json_object_add_uint (node, "current_bucket",
4728                             ntohl (mp->current_bucket));
4729   vat_json_object_add_uint (node, "extended_limit",
4730                             ntohl (mp->extended_limit));
4731   vat_json_object_add_uint (node, "extended_bucket",
4732                             ntohl (mp->extended_bucket));
4733   vat_json_object_add_uint (node, "last_update_time",
4734                             ntohl (mp->last_update_time));
4735   vat_json_object_add_string_copy (node, "conform_action",
4736                                    conform_action_str);
4737   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4738     {
4739       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4740       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4741       vec_free (dscp_str);
4742     }
4743   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4744   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4745     {
4746       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4747       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4748       vec_free (dscp_str);
4749     }
4750   vat_json_object_add_string_copy (node, "violate_action",
4751                                    violate_action_str);
4752   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4753     {
4754       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4755       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4756       vec_free (dscp_str);
4757     }
4758
4759   vec_free (rate_type_str);
4760   vec_free (round_type_str);
4761   vec_free (type_str);
4762   vec_free (conform_action_str);
4763   vec_free (exceed_action_str);
4764   vec_free (violate_action_str);
4765 }
4766
4767 static void
4768 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4769                                            mp)
4770 {
4771   vat_main_t *vam = &vat_main;
4772   int i, count = ntohl (mp->count);
4773
4774   if (count > 0)
4775     print (vam->ofp, "classify table ids (%d) : ", count);
4776   for (i = 0; i < count; i++)
4777     {
4778       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4779       print (vam->ofp, (i < count - 1) ? "," : "");
4780     }
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void
4786   vl_api_classify_table_ids_reply_t_handler_json
4787   (vl_api_classify_table_ids_reply_t * mp)
4788 {
4789   vat_main_t *vam = &vat_main;
4790   int i, count = ntohl (mp->count);
4791
4792   if (count > 0)
4793     {
4794       vat_json_node_t node;
4795
4796       vat_json_init_object (&node);
4797       for (i = 0; i < count; i++)
4798         {
4799           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4800         }
4801       vat_json_print (vam->ofp, &node);
4802       vat_json_free (&node);
4803     }
4804   vam->retval = ntohl (mp->retval);
4805   vam->result_ready = 1;
4806 }
4807
4808 static void
4809   vl_api_classify_table_by_interface_reply_t_handler
4810   (vl_api_classify_table_by_interface_reply_t * mp)
4811 {
4812   vat_main_t *vam = &vat_main;
4813   u32 table_id;
4814
4815   table_id = ntohl (mp->l2_table_id);
4816   if (table_id != ~0)
4817     print (vam->ofp, "l2 table id : %d", table_id);
4818   else
4819     print (vam->ofp, "l2 table id : No input ACL tables configured");
4820   table_id = ntohl (mp->ip4_table_id);
4821   if (table_id != ~0)
4822     print (vam->ofp, "ip4 table id : %d", table_id);
4823   else
4824     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4825   table_id = ntohl (mp->ip6_table_id);
4826   if (table_id != ~0)
4827     print (vam->ofp, "ip6 table id : %d", table_id);
4828   else
4829     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4830   vam->retval = ntohl (mp->retval);
4831   vam->result_ready = 1;
4832 }
4833
4834 static void
4835   vl_api_classify_table_by_interface_reply_t_handler_json
4836   (vl_api_classify_table_by_interface_reply_t * mp)
4837 {
4838   vat_main_t *vam = &vat_main;
4839   vat_json_node_t node;
4840
4841   vat_json_init_object (&node);
4842
4843   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4844   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4845   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4846
4847   vat_json_print (vam->ofp, &node);
4848   vat_json_free (&node);
4849
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void vl_api_policer_add_del_reply_t_handler
4855   (vl_api_policer_add_del_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   i32 retval = ntohl (mp->retval);
4859   if (vam->async_mode)
4860     {
4861       vam->async_errors += (retval < 0);
4862     }
4863   else
4864     {
4865       vam->retval = retval;
4866       vam->result_ready = 1;
4867       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4868         /*
4869          * Note: this is just barely thread-safe, depends on
4870          * the main thread spinning waiting for an answer...
4871          */
4872         errmsg ("policer index %d", ntohl (mp->policer_index));
4873     }
4874 }
4875
4876 static void vl_api_policer_add_del_reply_t_handler_json
4877   (vl_api_policer_add_del_reply_t * mp)
4878 {
4879   vat_main_t *vam = &vat_main;
4880   vat_json_node_t node;
4881
4882   vat_json_init_object (&node);
4883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4884   vat_json_object_add_uint (&node, "policer_index",
4885                             ntohl (mp->policer_index));
4886
4887   vat_json_print (vam->ofp, &node);
4888   vat_json_free (&node);
4889
4890   vam->retval = ntohl (mp->retval);
4891   vam->result_ready = 1;
4892 }
4893
4894 /* Format hex dump. */
4895 u8 *
4896 format_hex_bytes (u8 * s, va_list * va)
4897 {
4898   u8 *bytes = va_arg (*va, u8 *);
4899   int n_bytes = va_arg (*va, int);
4900   uword i;
4901
4902   /* Print short or long form depending on byte count. */
4903   uword short_form = n_bytes <= 32;
4904   u32 indent = format_get_indent (s);
4905
4906   if (n_bytes == 0)
4907     return s;
4908
4909   for (i = 0; i < n_bytes; i++)
4910     {
4911       if (!short_form && (i % 32) == 0)
4912         s = format (s, "%08x: ", i);
4913       s = format (s, "%02x", bytes[i]);
4914       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4915         s = format (s, "\n%U", format_white_space, indent);
4916     }
4917
4918   return s;
4919 }
4920
4921 static void
4922 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4923                                             * mp)
4924 {
4925   vat_main_t *vam = &vat_main;
4926   i32 retval = ntohl (mp->retval);
4927   if (retval == 0)
4928     {
4929       print (vam->ofp, "classify table info :");
4930       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4931              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4932              ntohl (mp->miss_next_index));
4933       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4934              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4935              ntohl (mp->match_n_vectors));
4936       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4937              ntohl (mp->mask_length));
4938     }
4939   vam->retval = retval;
4940   vam->result_ready = 1;
4941 }
4942
4943 static void
4944   vl_api_classify_table_info_reply_t_handler_json
4945   (vl_api_classify_table_info_reply_t * mp)
4946 {
4947   vat_main_t *vam = &vat_main;
4948   vat_json_node_t node;
4949
4950   i32 retval = ntohl (mp->retval);
4951   if (retval == 0)
4952     {
4953       vat_json_init_object (&node);
4954
4955       vat_json_object_add_int (&node, "sessions",
4956                                ntohl (mp->active_sessions));
4957       vat_json_object_add_int (&node, "nexttbl",
4958                                ntohl (mp->next_table_index));
4959       vat_json_object_add_int (&node, "nextnode",
4960                                ntohl (mp->miss_next_index));
4961       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4962       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4963       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4964       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4965                       ntohl (mp->mask_length), 0);
4966       vat_json_object_add_string_copy (&node, "mask", s);
4967
4968       vat_json_print (vam->ofp, &node);
4969       vat_json_free (&node);
4970     }
4971   vam->retval = ntohl (mp->retval);
4972   vam->result_ready = 1;
4973 }
4974
4975 static void
4976 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4977                                            mp)
4978 {
4979   vat_main_t *vam = &vat_main;
4980
4981   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4982          ntohl (mp->hit_next_index), ntohl (mp->advance),
4983          ntohl (mp->opaque_index));
4984   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4985          ntohl (mp->match_length));
4986 }
4987
4988 static void
4989   vl_api_classify_session_details_t_handler_json
4990   (vl_api_classify_session_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993   vat_json_node_t *node = NULL;
4994
4995   if (VAT_JSON_ARRAY != vam->json_tree.type)
4996     {
4997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4998       vat_json_init_array (&vam->json_tree);
4999     }
5000   node = vat_json_array_add (&vam->json_tree);
5001
5002   vat_json_init_object (node);
5003   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5004   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5005   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5006   u8 *s =
5007     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5008             0);
5009   vat_json_object_add_string_copy (node, "match", s);
5010 }
5011
5012 static void vl_api_pg_create_interface_reply_t_handler
5013   (vl_api_pg_create_interface_reply_t * mp)
5014 {
5015   vat_main_t *vam = &vat_main;
5016
5017   vam->retval = ntohl (mp->retval);
5018   vam->result_ready = 1;
5019 }
5020
5021 static void vl_api_pg_create_interface_reply_t_handler_json
5022   (vl_api_pg_create_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   i32 retval = ntohl (mp->retval);
5028   if (retval == 0)
5029     {
5030       vat_json_init_object (&node);
5031
5032       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5033
5034       vat_json_print (vam->ofp, &node);
5035       vat_json_free (&node);
5036     }
5037   vam->retval = ntohl (mp->retval);
5038   vam->result_ready = 1;
5039 }
5040
5041 static void vl_api_policer_classify_details_t_handler
5042   (vl_api_policer_classify_details_t * mp)
5043 {
5044   vat_main_t *vam = &vat_main;
5045
5046   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5047          ntohl (mp->table_index));
5048 }
5049
5050 static void vl_api_policer_classify_details_t_handler_json
5051   (vl_api_policer_classify_details_t * mp)
5052 {
5053   vat_main_t *vam = &vat_main;
5054   vat_json_node_t *node;
5055
5056   if (VAT_JSON_ARRAY != vam->json_tree.type)
5057     {
5058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5059       vat_json_init_array (&vam->json_tree);
5060     }
5061   node = vat_json_array_add (&vam->json_tree);
5062
5063   vat_json_init_object (node);
5064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5065   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5066 }
5067
5068 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5069   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072   i32 retval = ntohl (mp->retval);
5073   if (vam->async_mode)
5074     {
5075       vam->async_errors += (retval < 0);
5076     }
5077   else
5078     {
5079       vam->retval = retval;
5080       vam->sw_if_index = ntohl (mp->sw_if_index);
5081       vam->result_ready = 1;
5082     }
5083 }
5084
5085 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5086   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5087 {
5088   vat_main_t *vam = &vat_main;
5089   vat_json_node_t node;
5090
5091   vat_json_init_object (&node);
5092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5093   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5094
5095   vat_json_print (vam->ofp, &node);
5096   vat_json_free (&node);
5097
5098   vam->retval = ntohl (mp->retval);
5099   vam->result_ready = 1;
5100 }
5101
5102 static void vl_api_flow_classify_details_t_handler
5103   (vl_api_flow_classify_details_t * mp)
5104 {
5105   vat_main_t *vam = &vat_main;
5106
5107   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5108          ntohl (mp->table_index));
5109 }
5110
5111 static void vl_api_flow_classify_details_t_handler_json
5112   (vl_api_flow_classify_details_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t *node;
5116
5117   if (VAT_JSON_ARRAY != vam->json_tree.type)
5118     {
5119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5120       vat_json_init_array (&vam->json_tree);
5121     }
5122   node = vat_json_array_add (&vam->json_tree);
5123
5124   vat_json_init_object (node);
5125   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5126   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5127 }
5128
5129 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5130 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5131 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5132 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5133 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5134 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5135 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5136 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5137 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5138 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5139 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5140 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5141 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5142 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5143 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5144 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5145 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5146 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5147 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5148 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5149 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5150 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5151
5152 /*
5153  * Generate boilerplate reply handlers, which
5154  * dig the return value out of the xxx_reply_t API message,
5155  * stick it into vam->retval, and set vam->result_ready
5156  *
5157  * Could also do this by pointing N message decode slots at
5158  * a single function, but that could break in subtle ways.
5159  */
5160
5161 #define foreach_standard_reply_retval_handler           \
5162 _(sw_interface_set_flags_reply)                         \
5163 _(sw_interface_add_del_address_reply)                   \
5164 _(sw_interface_set_rx_mode_reply)                       \
5165 _(sw_interface_set_table_reply)                         \
5166 _(sw_interface_set_mpls_enable_reply)                   \
5167 _(sw_interface_set_vpath_reply)                         \
5168 _(sw_interface_set_vxlan_bypass_reply)                  \
5169 _(sw_interface_set_geneve_bypass_reply)                 \
5170 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5171 _(sw_interface_set_l2_bridge_reply)                     \
5172 _(bridge_domain_add_del_reply)                          \
5173 _(sw_interface_set_l2_xconnect_reply)                   \
5174 _(l2fib_add_del_reply)                                  \
5175 _(l2fib_flush_int_reply)                                \
5176 _(l2fib_flush_bd_reply)                                 \
5177 _(ip_add_del_route_reply)                               \
5178 _(ip_table_add_del_reply)                               \
5179 _(ip_mroute_add_del_reply)                              \
5180 _(mpls_route_add_del_reply)                             \
5181 _(mpls_table_add_del_reply)                             \
5182 _(mpls_ip_bind_unbind_reply)                            \
5183 _(bier_route_add_del_reply)                             \
5184 _(bier_table_add_del_reply)                             \
5185 _(proxy_arp_add_del_reply)                              \
5186 _(proxy_arp_intfc_enable_disable_reply)                 \
5187 _(sw_interface_set_unnumbered_reply)                    \
5188 _(ip_neighbor_add_del_reply)                            \
5189 _(oam_add_del_reply)                                    \
5190 _(reset_fib_reply)                                      \
5191 _(dhcp_proxy_config_reply)                              \
5192 _(dhcp_proxy_set_vss_reply)                             \
5193 _(dhcp_client_config_reply)                             \
5194 _(set_ip_flow_hash_reply)                               \
5195 _(sw_interface_ip6_enable_disable_reply)                \
5196 _(sw_interface_ip6_set_link_local_address_reply)        \
5197 _(ip6nd_proxy_add_del_reply)                            \
5198 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5199 _(sw_interface_ip6nd_ra_config_reply)                   \
5200 _(set_arp_neighbor_limit_reply)                         \
5201 _(l2_patch_add_del_reply)                               \
5202 _(sr_policy_add_reply)                                  \
5203 _(sr_policy_mod_reply)                                  \
5204 _(sr_policy_del_reply)                                  \
5205 _(sr_localsid_add_del_reply)                            \
5206 _(sr_steering_add_del_reply)                            \
5207 _(classify_add_del_session_reply)                       \
5208 _(classify_set_interface_ip_table_reply)                \
5209 _(classify_set_interface_l2_tables_reply)               \
5210 _(l2tpv3_set_tunnel_cookies_reply)                      \
5211 _(l2tpv3_interface_enable_disable_reply)                \
5212 _(l2tpv3_set_lookup_key_reply)                          \
5213 _(l2_fib_clear_table_reply)                             \
5214 _(l2_interface_efp_filter_reply)                        \
5215 _(l2_interface_vlan_tag_rewrite_reply)                  \
5216 _(modify_vhost_user_if_reply)                           \
5217 _(delete_vhost_user_if_reply)                           \
5218 _(want_ip4_arp_events_reply)                            \
5219 _(want_ip6_nd_events_reply)                             \
5220 _(want_l2_macs_events_reply)                            \
5221 _(input_acl_set_interface_reply)                        \
5222 _(ipsec_spd_add_del_reply)                              \
5223 _(ipsec_interface_add_del_spd_reply)                    \
5224 _(ipsec_spd_add_del_entry_reply)                        \
5225 _(ipsec_sad_add_del_entry_reply)                        \
5226 _(ipsec_sa_set_key_reply)                               \
5227 _(ipsec_tunnel_if_add_del_reply)                        \
5228 _(ipsec_tunnel_if_set_key_reply)                        \
5229 _(ipsec_tunnel_if_set_sa_reply)                         \
5230 _(ikev2_profile_add_del_reply)                          \
5231 _(ikev2_profile_set_auth_reply)                         \
5232 _(ikev2_profile_set_id_reply)                           \
5233 _(ikev2_profile_set_ts_reply)                           \
5234 _(ikev2_set_local_key_reply)                            \
5235 _(ikev2_set_responder_reply)                            \
5236 _(ikev2_set_ike_transforms_reply)                       \
5237 _(ikev2_set_esp_transforms_reply)                       \
5238 _(ikev2_set_sa_lifetime_reply)                          \
5239 _(ikev2_initiate_sa_init_reply)                         \
5240 _(ikev2_initiate_del_ike_sa_reply)                      \
5241 _(ikev2_initiate_del_child_sa_reply)                    \
5242 _(ikev2_initiate_rekey_child_sa_reply)                  \
5243 _(delete_loopback_reply)                                \
5244 _(bd_ip_mac_add_del_reply)                              \
5245 _(map_del_domain_reply)                                 \
5246 _(map_add_del_rule_reply)                               \
5247 _(want_interface_events_reply)                          \
5248 _(want_stats_reply)                                     \
5249 _(cop_interface_enable_disable_reply)                   \
5250 _(cop_whitelist_enable_disable_reply)                   \
5251 _(sw_interface_clear_stats_reply)                       \
5252 _(ioam_enable_reply)                                    \
5253 _(ioam_disable_reply)                                   \
5254 _(one_add_del_locator_reply)                            \
5255 _(one_add_del_local_eid_reply)                          \
5256 _(one_add_del_remote_mapping_reply)                     \
5257 _(one_add_del_adjacency_reply)                          \
5258 _(one_add_del_map_resolver_reply)                       \
5259 _(one_add_del_map_server_reply)                         \
5260 _(one_enable_disable_reply)                             \
5261 _(one_rloc_probe_enable_disable_reply)                  \
5262 _(one_map_register_enable_disable_reply)                \
5263 _(one_map_register_set_ttl_reply)                       \
5264 _(one_set_transport_protocol_reply)                     \
5265 _(one_map_register_fallback_threshold_reply)            \
5266 _(one_pitr_set_locator_set_reply)                       \
5267 _(one_map_request_mode_reply)                           \
5268 _(one_add_del_map_request_itr_rlocs_reply)              \
5269 _(one_eid_table_add_del_map_reply)                      \
5270 _(one_use_petr_reply)                                   \
5271 _(one_stats_enable_disable_reply)                       \
5272 _(one_add_del_l2_arp_entry_reply)                       \
5273 _(one_add_del_ndp_entry_reply)                          \
5274 _(one_stats_flush_reply)                                \
5275 _(one_enable_disable_xtr_mode_reply)                    \
5276 _(one_enable_disable_pitr_mode_reply)                   \
5277 _(one_enable_disable_petr_mode_reply)                   \
5278 _(gpe_enable_disable_reply)                             \
5279 _(gpe_set_encap_mode_reply)                             \
5280 _(gpe_add_del_iface_reply)                              \
5281 _(gpe_add_del_native_fwd_rpath_reply)                   \
5282 _(af_packet_delete_reply)                               \
5283 _(policer_classify_set_interface_reply)                 \
5284 _(netmap_create_reply)                                  \
5285 _(netmap_delete_reply)                                  \
5286 _(set_ipfix_exporter_reply)                             \
5287 _(set_ipfix_classify_stream_reply)                      \
5288 _(ipfix_classify_table_add_del_reply)                   \
5289 _(flow_classify_set_interface_reply)                    \
5290 _(sw_interface_span_enable_disable_reply)               \
5291 _(pg_capture_reply)                                     \
5292 _(pg_enable_disable_reply)                              \
5293 _(ip_source_and_port_range_check_add_del_reply)         \
5294 _(ip_source_and_port_range_check_interface_add_del_reply)\
5295 _(delete_subif_reply)                                   \
5296 _(l2_interface_pbb_tag_rewrite_reply)                   \
5297 _(punt_reply)                                           \
5298 _(feature_enable_disable_reply)                         \
5299 _(sw_interface_tag_add_del_reply)                       \
5300 _(sw_interface_set_mtu_reply)                           \
5301 _(p2p_ethernet_add_reply)                               \
5302 _(p2p_ethernet_del_reply)                               \
5303 _(lldp_config_reply)                                    \
5304 _(sw_interface_set_lldp_reply)                          \
5305 _(tcp_configure_src_addresses_reply)                    \
5306 _(dns_enable_disable_reply)                             \
5307 _(dns_name_server_add_del_reply)                        \
5308 _(session_rule_add_del_reply)                           \
5309 _(ip_container_proxy_add_del_reply)
5310
5311 #define _(n)                                    \
5312     static void vl_api_##n##_t_handler          \
5313     (vl_api_##n##_t * mp)                       \
5314     {                                           \
5315         vat_main_t * vam = &vat_main;           \
5316         i32 retval = ntohl(mp->retval);         \
5317         if (vam->async_mode) {                  \
5318             vam->async_errors += (retval < 0);  \
5319         } else {                                \
5320             vam->retval = retval;               \
5321             vam->result_ready = 1;              \
5322         }                                       \
5323     }
5324 foreach_standard_reply_retval_handler;
5325 #undef _
5326
5327 #define _(n)                                    \
5328     static void vl_api_##n##_t_handler_json     \
5329     (vl_api_##n##_t * mp)                       \
5330     {                                           \
5331         vat_main_t * vam = &vat_main;           \
5332         vat_json_node_t node;                   \
5333         vat_json_init_object(&node);            \
5334         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5335         vat_json_print(vam->ofp, &node);        \
5336         vam->retval = ntohl(mp->retval);        \
5337         vam->result_ready = 1;                  \
5338     }
5339 foreach_standard_reply_retval_handler;
5340 #undef _
5341
5342 /*
5343  * Table of message reply handlers, must include boilerplate handlers
5344  * we just generated
5345  */
5346
5347 #define foreach_vpe_api_reply_msg                                       \
5348 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5349 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5350 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5351 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5352 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5353 _(CLI_REPLY, cli_reply)                                                 \
5354 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5355 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5356   sw_interface_add_del_address_reply)                                   \
5357 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5358 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5359 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5360 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5361 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5362 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5363 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5364 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5365   sw_interface_set_l2_xconnect_reply)                                   \
5366 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5367   sw_interface_set_l2_bridge_reply)                                     \
5368 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5369 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5370 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5371 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5372 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5373 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5374 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5375 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5376 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5377 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5378 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5379 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5380 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5381 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5382 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5383 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5384 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5385 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5386 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5387 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5388 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5389 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5390   proxy_arp_intfc_enable_disable_reply)                                 \
5391 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5392 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5393   sw_interface_set_unnumbered_reply)                                    \
5394 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5395 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5396 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5397 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5398 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5399 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5400 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5401 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5402 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5403 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5404 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5405   sw_interface_ip6_enable_disable_reply)                                \
5406 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5407   sw_interface_ip6_set_link_local_address_reply)                        \
5408 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5409 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5410 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5411   sw_interface_ip6nd_ra_prefix_reply)                                   \
5412 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5413   sw_interface_ip6nd_ra_config_reply)                                   \
5414 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5415 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5416 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5417 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5418 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5419 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5420 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5421 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5422 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5423 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5424 classify_set_interface_ip_table_reply)                                  \
5425 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5426   classify_set_interface_l2_tables_reply)                               \
5427 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5428 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5429 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5430 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5431 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5432   l2tpv3_interface_enable_disable_reply)                                \
5433 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5434 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5435 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5436 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5437 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5438 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5439 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5440 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5441 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5442 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5443 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5444 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5445 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5446 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5447 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5448 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5449 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5450 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5451 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5452 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5453 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5454 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5455 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5456 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5457 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5458 _(L2_MACS_EVENT, l2_macs_event)                                         \
5459 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5460 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5461 _(IP_DETAILS, ip_details)                                               \
5462 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5463 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5464 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5465 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5466 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5467 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5468 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5469 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5470 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5471 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5472 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5473 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5474 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5475 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5476 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5477 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5478 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5479 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5480 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5481 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5482 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5483 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5484 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5485 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5486 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5487 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5488 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5489 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5490 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5491 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5492 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5493 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5494 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5495 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5496 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5497 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5498 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5499 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5500 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5501 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5502 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5503 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5504 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5505 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5506 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5507 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5508 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5509 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5510   one_map_register_enable_disable_reply)                                \
5511 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5512 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5513 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5514 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5515   one_map_register_fallback_threshold_reply)                            \
5516 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5517   one_rloc_probe_enable_disable_reply)                                  \
5518 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5519 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5520 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5521 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5522 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5523 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5524 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5525 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5526 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5527 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5528 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5529 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5530 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5531 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5532 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5533 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5534   show_one_stats_enable_disable_reply)                                  \
5535 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5536 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5537 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5538 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5539 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5540 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5541 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5542 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5543   one_enable_disable_pitr_mode_reply)                                   \
5544 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5545   one_enable_disable_petr_mode_reply)                                   \
5546 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5547 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5548 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5549 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5550 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5551 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5552 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5553 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5554 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5555 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5556 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5557 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5558   gpe_add_del_native_fwd_rpath_reply)                                   \
5559 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5560   gpe_fwd_entry_path_details)                                           \
5561 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5562 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5563   one_add_del_map_request_itr_rlocs_reply)                              \
5564 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5565   one_get_map_request_itr_rlocs_reply)                                  \
5566 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5567 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5568 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5569 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5570 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5571 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5572   show_one_map_register_state_reply)                                    \
5573 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5574 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5575   show_one_map_register_fallback_threshold_reply)                       \
5576 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5577 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5578 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5579 _(POLICER_DETAILS, policer_details)                                     \
5580 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5581 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5582 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5583 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5584 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5585 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5586 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5587 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5588 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5589 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5590 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5591 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5592 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5593 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5594 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5595 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5596 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5597 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5598 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5599 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5600 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5601 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5602 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5603 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5604 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5605  ip_source_and_port_range_check_add_del_reply)                          \
5606 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5607  ip_source_and_port_range_check_interface_add_del_reply)                \
5608 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5609 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5610 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5611 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5612 _(PUNT_REPLY, punt_reply)                                               \
5613 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5614 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5615 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5616 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5617 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5618 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5619 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5620 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5621 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5622 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5623 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5624 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5625 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5626 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5627 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5628 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5629 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5630 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5631 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5632 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5633 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5634
5635 #define foreach_standalone_reply_msg                                    \
5636 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5637 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5638 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5639 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5640 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5641 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5642 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5643 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5644
5645 typedef struct
5646 {
5647   u8 *name;
5648   u32 value;
5649 } name_sort_t;
5650
5651
5652 #define STR_VTR_OP_CASE(op)     \
5653     case L2_VTR_ ## op:         \
5654         return "" # op;
5655
5656 static const char *
5657 str_vtr_op (u32 vtr_op)
5658 {
5659   switch (vtr_op)
5660     {
5661       STR_VTR_OP_CASE (DISABLED);
5662       STR_VTR_OP_CASE (PUSH_1);
5663       STR_VTR_OP_CASE (PUSH_2);
5664       STR_VTR_OP_CASE (POP_1);
5665       STR_VTR_OP_CASE (POP_2);
5666       STR_VTR_OP_CASE (TRANSLATE_1_1);
5667       STR_VTR_OP_CASE (TRANSLATE_1_2);
5668       STR_VTR_OP_CASE (TRANSLATE_2_1);
5669       STR_VTR_OP_CASE (TRANSLATE_2_2);
5670     }
5671
5672   return "UNKNOWN";
5673 }
5674
5675 static int
5676 dump_sub_interface_table (vat_main_t * vam)
5677 {
5678   const sw_interface_subif_t *sub = NULL;
5679
5680   if (vam->json_output)
5681     {
5682       clib_warning
5683         ("JSON output supported only for VPE API calls and dump_stats_table");
5684       return -99;
5685     }
5686
5687   print (vam->ofp,
5688          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5689          "Interface", "sw_if_index",
5690          "sub id", "dot1ad", "tags", "outer id",
5691          "inner id", "exact", "default", "outer any", "inner any");
5692
5693   vec_foreach (sub, vam->sw_if_subif_table)
5694   {
5695     print (vam->ofp,
5696            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5697            sub->interface_name,
5698            sub->sw_if_index,
5699            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5700            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5701            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5702            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5703     if (sub->vtr_op != L2_VTR_DISABLED)
5704       {
5705         print (vam->ofp,
5706                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5707                "tag1: %d tag2: %d ]",
5708                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5709                sub->vtr_tag1, sub->vtr_tag2);
5710       }
5711   }
5712
5713   return 0;
5714 }
5715
5716 static int
5717 name_sort_cmp (void *a1, void *a2)
5718 {
5719   name_sort_t *n1 = a1;
5720   name_sort_t *n2 = a2;
5721
5722   return strcmp ((char *) n1->name, (char *) n2->name);
5723 }
5724
5725 static int
5726 dump_interface_table (vat_main_t * vam)
5727 {
5728   hash_pair_t *p;
5729   name_sort_t *nses = 0, *ns;
5730
5731   if (vam->json_output)
5732     {
5733       clib_warning
5734         ("JSON output supported only for VPE API calls and dump_stats_table");
5735       return -99;
5736     }
5737
5738   /* *INDENT-OFF* */
5739   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5740   ({
5741     vec_add2 (nses, ns, 1);
5742     ns->name = (u8 *)(p->key);
5743     ns->value = (u32) p->value[0];
5744   }));
5745   /* *INDENT-ON* */
5746
5747   vec_sort_with_function (nses, name_sort_cmp);
5748
5749   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5750   vec_foreach (ns, nses)
5751   {
5752     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5753   }
5754   vec_free (nses);
5755   return 0;
5756 }
5757
5758 static int
5759 dump_ip_table (vat_main_t * vam, int is_ipv6)
5760 {
5761   const ip_details_t *det = NULL;
5762   const ip_address_details_t *address = NULL;
5763   u32 i = ~0;
5764
5765   print (vam->ofp, "%-12s", "sw_if_index");
5766
5767   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5768   {
5769     i++;
5770     if (!det->present)
5771       {
5772         continue;
5773       }
5774     print (vam->ofp, "%-12d", i);
5775     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5776     if (!det->addr)
5777       {
5778         continue;
5779       }
5780     vec_foreach (address, det->addr)
5781     {
5782       print (vam->ofp,
5783              "            %-30U%-13d",
5784              is_ipv6 ? format_ip6_address : format_ip4_address,
5785              address->ip, address->prefix_length);
5786     }
5787   }
5788
5789   return 0;
5790 }
5791
5792 static int
5793 dump_ipv4_table (vat_main_t * vam)
5794 {
5795   if (vam->json_output)
5796     {
5797       clib_warning
5798         ("JSON output supported only for VPE API calls and dump_stats_table");
5799       return -99;
5800     }
5801
5802   return dump_ip_table (vam, 0);
5803 }
5804
5805 static int
5806 dump_ipv6_table (vat_main_t * vam)
5807 {
5808   if (vam->json_output)
5809     {
5810       clib_warning
5811         ("JSON output supported only for VPE API calls and dump_stats_table");
5812       return -99;
5813     }
5814
5815   return dump_ip_table (vam, 1);
5816 }
5817
5818 static char *
5819 counter_type_to_str (u8 counter_type, u8 is_combined)
5820 {
5821   if (!is_combined)
5822     {
5823       switch (counter_type)
5824         {
5825         case VNET_INTERFACE_COUNTER_DROP:
5826           return "drop";
5827         case VNET_INTERFACE_COUNTER_PUNT:
5828           return "punt";
5829         case VNET_INTERFACE_COUNTER_IP4:
5830           return "ip4";
5831         case VNET_INTERFACE_COUNTER_IP6:
5832           return "ip6";
5833         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5834           return "rx-no-buf";
5835         case VNET_INTERFACE_COUNTER_RX_MISS:
5836           return "rx-miss";
5837         case VNET_INTERFACE_COUNTER_RX_ERROR:
5838           return "rx-error";
5839         case VNET_INTERFACE_COUNTER_TX_ERROR:
5840           return "tx-error";
5841         default:
5842           return "INVALID-COUNTER-TYPE";
5843         }
5844     }
5845   else
5846     {
5847       switch (counter_type)
5848         {
5849         case VNET_INTERFACE_COUNTER_RX:
5850           return "rx";
5851         case VNET_INTERFACE_COUNTER_TX:
5852           return "tx";
5853         default:
5854           return "INVALID-COUNTER-TYPE";
5855         }
5856     }
5857 }
5858
5859 static int
5860 dump_stats_table (vat_main_t * vam)
5861 {
5862   vat_json_node_t node;
5863   vat_json_node_t *msg_array;
5864   vat_json_node_t *msg;
5865   vat_json_node_t *counter_array;
5866   vat_json_node_t *counter;
5867   interface_counter_t c;
5868   u64 packets;
5869   ip4_fib_counter_t *c4;
5870   ip6_fib_counter_t *c6;
5871   ip4_nbr_counter_t *n4;
5872   ip6_nbr_counter_t *n6;
5873   int i, j;
5874
5875   if (!vam->json_output)
5876     {
5877       clib_warning ("dump_stats_table supported only in JSON format");
5878       return -99;
5879     }
5880
5881   vat_json_init_object (&node);
5882
5883   /* interface counters */
5884   msg_array = vat_json_object_add (&node, "interface_counters");
5885   vat_json_init_array (msg_array);
5886   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5887     {
5888       msg = vat_json_array_add (msg_array);
5889       vat_json_init_object (msg);
5890       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5891                                        (u8 *) counter_type_to_str (i, 0));
5892       vat_json_object_add_int (msg, "is_combined", 0);
5893       counter_array = vat_json_object_add (msg, "data");
5894       vat_json_init_array (counter_array);
5895       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5896         {
5897           packets = vam->simple_interface_counters[i][j];
5898           vat_json_array_add_uint (counter_array, packets);
5899         }
5900     }
5901   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5902     {
5903       msg = vat_json_array_add (msg_array);
5904       vat_json_init_object (msg);
5905       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5906                                        (u8 *) counter_type_to_str (i, 1));
5907       vat_json_object_add_int (msg, "is_combined", 1);
5908       counter_array = vat_json_object_add (msg, "data");
5909       vat_json_init_array (counter_array);
5910       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5911         {
5912           c = vam->combined_interface_counters[i][j];
5913           counter = vat_json_array_add (counter_array);
5914           vat_json_init_object (counter);
5915           vat_json_object_add_uint (counter, "packets", c.packets);
5916           vat_json_object_add_uint (counter, "bytes", c.bytes);
5917         }
5918     }
5919
5920   /* ip4 fib counters */
5921   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5922   vat_json_init_array (msg_array);
5923   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5924     {
5925       msg = vat_json_array_add (msg_array);
5926       vat_json_init_object (msg);
5927       vat_json_object_add_uint (msg, "vrf_id",
5928                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5929       counter_array = vat_json_object_add (msg, "c");
5930       vat_json_init_array (counter_array);
5931       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5932         {
5933           counter = vat_json_array_add (counter_array);
5934           vat_json_init_object (counter);
5935           c4 = &vam->ip4_fib_counters[i][j];
5936           vat_json_object_add_ip4 (counter, "address", c4->address);
5937           vat_json_object_add_uint (counter, "address_length",
5938                                     c4->address_length);
5939           vat_json_object_add_uint (counter, "packets", c4->packets);
5940           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5941         }
5942     }
5943
5944   /* ip6 fib counters */
5945   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5946   vat_json_init_array (msg_array);
5947   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5948     {
5949       msg = vat_json_array_add (msg_array);
5950       vat_json_init_object (msg);
5951       vat_json_object_add_uint (msg, "vrf_id",
5952                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5953       counter_array = vat_json_object_add (msg, "c");
5954       vat_json_init_array (counter_array);
5955       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5956         {
5957           counter = vat_json_array_add (counter_array);
5958           vat_json_init_object (counter);
5959           c6 = &vam->ip6_fib_counters[i][j];
5960           vat_json_object_add_ip6 (counter, "address", c6->address);
5961           vat_json_object_add_uint (counter, "address_length",
5962                                     c6->address_length);
5963           vat_json_object_add_uint (counter, "packets", c6->packets);
5964           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5965         }
5966     }
5967
5968   /* ip4 nbr counters */
5969   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5970   vat_json_init_array (msg_array);
5971   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5972     {
5973       msg = vat_json_array_add (msg_array);
5974       vat_json_init_object (msg);
5975       vat_json_object_add_uint (msg, "sw_if_index", i);
5976       counter_array = vat_json_object_add (msg, "c");
5977       vat_json_init_array (counter_array);
5978       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5979         {
5980           counter = vat_json_array_add (counter_array);
5981           vat_json_init_object (counter);
5982           n4 = &vam->ip4_nbr_counters[i][j];
5983           vat_json_object_add_ip4 (counter, "address", n4->address);
5984           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5985           vat_json_object_add_uint (counter, "packets", n4->packets);
5986           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5987         }
5988     }
5989
5990   /* ip6 nbr counters */
5991   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5992   vat_json_init_array (msg_array);
5993   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5994     {
5995       msg = vat_json_array_add (msg_array);
5996       vat_json_init_object (msg);
5997       vat_json_object_add_uint (msg, "sw_if_index", i);
5998       counter_array = vat_json_object_add (msg, "c");
5999       vat_json_init_array (counter_array);
6000       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6001         {
6002           counter = vat_json_array_add (counter_array);
6003           vat_json_init_object (counter);
6004           n6 = &vam->ip6_nbr_counters[i][j];
6005           vat_json_object_add_ip6 (counter, "address", n6->address);
6006           vat_json_object_add_uint (counter, "packets", n6->packets);
6007           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6008         }
6009     }
6010
6011   vat_json_print (vam->ofp, &node);
6012   vat_json_free (&node);
6013
6014   return 0;
6015 }
6016
6017 /*
6018  * Pass CLI buffers directly in the CLI_INBAND API message,
6019  * instead of an additional shared memory area.
6020  */
6021 static int
6022 exec_inband (vat_main_t * vam)
6023 {
6024   vl_api_cli_inband_t *mp;
6025   unformat_input_t *i = vam->input;
6026   int ret;
6027
6028   if (vec_len (i->buffer) == 0)
6029     return -1;
6030
6031   if (vam->exec_mode == 0 && unformat (i, "mode"))
6032     {
6033       vam->exec_mode = 1;
6034       return 0;
6035     }
6036   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6037     {
6038       vam->exec_mode = 0;
6039       return 0;
6040     }
6041
6042   /*
6043    * In order for the CLI command to work, it
6044    * must be a vector ending in \n, not a C-string ending
6045    * in \n\0.
6046    */
6047   u32 len = vec_len (vam->input->buffer);
6048   M2 (CLI_INBAND, mp, len);
6049   clib_memcpy (mp->cmd, vam->input->buffer, len);
6050   mp->length = htonl (len);
6051
6052   S (mp);
6053   W (ret);
6054   /* json responses may or may not include a useful reply... */
6055   if (vec_len (vam->cmd_reply))
6056     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6057   return ret;
6058 }
6059
6060 int
6061 exec (vat_main_t * vam)
6062 {
6063   return exec_inband (vam);
6064 }
6065
6066 static int
6067 api_create_loopback (vat_main_t * vam)
6068 {
6069   unformat_input_t *i = vam->input;
6070   vl_api_create_loopback_t *mp;
6071   vl_api_create_loopback_instance_t *mp_lbi;
6072   u8 mac_address[6];
6073   u8 mac_set = 0;
6074   u8 is_specified = 0;
6075   u32 user_instance = 0;
6076   int ret;
6077
6078   memset (mac_address, 0, sizeof (mac_address));
6079
6080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6081     {
6082       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6083         mac_set = 1;
6084       if (unformat (i, "instance %d", &user_instance))
6085         is_specified = 1;
6086       else
6087         break;
6088     }
6089
6090   if (is_specified)
6091     {
6092       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6093       mp_lbi->is_specified = is_specified;
6094       if (is_specified)
6095         mp_lbi->user_instance = htonl (user_instance);
6096       if (mac_set)
6097         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6098       S (mp_lbi);
6099     }
6100   else
6101     {
6102       /* Construct the API message */
6103       M (CREATE_LOOPBACK, mp);
6104       if (mac_set)
6105         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6106       S (mp);
6107     }
6108
6109   W (ret);
6110   return ret;
6111 }
6112
6113 static int
6114 api_delete_loopback (vat_main_t * vam)
6115 {
6116   unformat_input_t *i = vam->input;
6117   vl_api_delete_loopback_t *mp;
6118   u32 sw_if_index = ~0;
6119   int ret;
6120
6121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6122     {
6123       if (unformat (i, "sw_if_index %d", &sw_if_index))
6124         ;
6125       else
6126         break;
6127     }
6128
6129   if (sw_if_index == ~0)
6130     {
6131       errmsg ("missing sw_if_index");
6132       return -99;
6133     }
6134
6135   /* Construct the API message */
6136   M (DELETE_LOOPBACK, mp);
6137   mp->sw_if_index = ntohl (sw_if_index);
6138
6139   S (mp);
6140   W (ret);
6141   return ret;
6142 }
6143
6144 static int
6145 api_want_stats (vat_main_t * vam)
6146 {
6147   unformat_input_t *i = vam->input;
6148   vl_api_want_stats_t *mp;
6149   int enable = -1;
6150   int ret;
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "enable"))
6155         enable = 1;
6156       else if (unformat (i, "disable"))
6157         enable = 0;
6158       else
6159         break;
6160     }
6161
6162   if (enable == -1)
6163     {
6164       errmsg ("missing enable|disable");
6165       return -99;
6166     }
6167
6168   M (WANT_STATS, mp);
6169   mp->enable_disable = enable;
6170
6171   S (mp);
6172   W (ret);
6173   return ret;
6174 }
6175
6176 static int
6177 api_want_interface_events (vat_main_t * vam)
6178 {
6179   unformat_input_t *i = vam->input;
6180   vl_api_want_interface_events_t *mp;
6181   int enable = -1;
6182   int ret;
6183
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "enable"))
6187         enable = 1;
6188       else if (unformat (i, "disable"))
6189         enable = 0;
6190       else
6191         break;
6192     }
6193
6194   if (enable == -1)
6195     {
6196       errmsg ("missing enable|disable");
6197       return -99;
6198     }
6199
6200   M (WANT_INTERFACE_EVENTS, mp);
6201   mp->enable_disable = enable;
6202
6203   vam->interface_event_display = enable;
6204
6205   S (mp);
6206   W (ret);
6207   return ret;
6208 }
6209
6210
6211 /* Note: non-static, called once to set up the initial intfc table */
6212 int
6213 api_sw_interface_dump (vat_main_t * vam)
6214 {
6215   vl_api_sw_interface_dump_t *mp;
6216   vl_api_control_ping_t *mp_ping;
6217   hash_pair_t *p;
6218   name_sort_t *nses = 0, *ns;
6219   sw_interface_subif_t *sub = NULL;
6220   int ret;
6221
6222   /* Toss the old name table */
6223   /* *INDENT-OFF* */
6224   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6225   ({
6226     vec_add2 (nses, ns, 1);
6227     ns->name = (u8 *)(p->key);
6228     ns->value = (u32) p->value[0];
6229   }));
6230   /* *INDENT-ON* */
6231
6232   hash_free (vam->sw_if_index_by_interface_name);
6233
6234   vec_foreach (ns, nses) vec_free (ns->name);
6235
6236   vec_free (nses);
6237
6238   vec_foreach (sub, vam->sw_if_subif_table)
6239   {
6240     vec_free (sub->interface_name);
6241   }
6242   vec_free (vam->sw_if_subif_table);
6243
6244   /* recreate the interface name hash table */
6245   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6246
6247   /* Get list of ethernets */
6248   M (SW_INTERFACE_DUMP, mp);
6249   mp->name_filter_valid = 1;
6250   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6251   S (mp);
6252
6253   /* and local / loopback interfaces */
6254   M (SW_INTERFACE_DUMP, mp);
6255   mp->name_filter_valid = 1;
6256   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6257   S (mp);
6258
6259   /* and packet-generator interfaces */
6260   M (SW_INTERFACE_DUMP, mp);
6261   mp->name_filter_valid = 1;
6262   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6263   S (mp);
6264
6265   /* and vxlan-gpe tunnel interfaces */
6266   M (SW_INTERFACE_DUMP, mp);
6267   mp->name_filter_valid = 1;
6268   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6269            sizeof (mp->name_filter) - 1);
6270   S (mp);
6271
6272   /* and vxlan tunnel interfaces */
6273   M (SW_INTERFACE_DUMP, mp);
6274   mp->name_filter_valid = 1;
6275   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6276   S (mp);
6277
6278   /* and geneve tunnel interfaces */
6279   M (SW_INTERFACE_DUMP, mp);
6280   mp->name_filter_valid = 1;
6281   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6282   S (mp);
6283
6284   /* and host (af_packet) interfaces */
6285   M (SW_INTERFACE_DUMP, mp);
6286   mp->name_filter_valid = 1;
6287   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6288   S (mp);
6289
6290   /* and l2tpv3 tunnel interfaces */
6291   M (SW_INTERFACE_DUMP, mp);
6292   mp->name_filter_valid = 1;
6293   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6294            sizeof (mp->name_filter) - 1);
6295   S (mp);
6296
6297   /* and GRE tunnel interfaces */
6298   M (SW_INTERFACE_DUMP, mp);
6299   mp->name_filter_valid = 1;
6300   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6301   S (mp);
6302
6303   /* and LISP-GPE interfaces */
6304   M (SW_INTERFACE_DUMP, mp);
6305   mp->name_filter_valid = 1;
6306   strncpy ((char *) mp->name_filter, "lisp_gpe",
6307            sizeof (mp->name_filter) - 1);
6308   S (mp);
6309
6310   /* and IPSEC tunnel interfaces */
6311   M (SW_INTERFACE_DUMP, mp);
6312   mp->name_filter_valid = 1;
6313   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6314   S (mp);
6315
6316   /* Use a control ping for synchronization */
6317   MPING (CONTROL_PING, mp_ping);
6318   S (mp_ping);
6319
6320   W (ret);
6321   return ret;
6322 }
6323
6324 static int
6325 api_sw_interface_set_flags (vat_main_t * vam)
6326 {
6327   unformat_input_t *i = vam->input;
6328   vl_api_sw_interface_set_flags_t *mp;
6329   u32 sw_if_index;
6330   u8 sw_if_index_set = 0;
6331   u8 admin_up = 0;
6332   int ret;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "admin-up"))
6338         admin_up = 1;
6339       else if (unformat (i, "admin-down"))
6340         admin_up = 0;
6341       else
6342         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6343         sw_if_index_set = 1;
6344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6345         sw_if_index_set = 1;
6346       else
6347         break;
6348     }
6349
6350   if (sw_if_index_set == 0)
6351     {
6352       errmsg ("missing interface name or sw_if_index");
6353       return -99;
6354     }
6355
6356   /* Construct the API message */
6357   M (SW_INTERFACE_SET_FLAGS, mp);
6358   mp->sw_if_index = ntohl (sw_if_index);
6359   mp->admin_up_down = admin_up;
6360
6361   /* send it... */
6362   S (mp);
6363
6364   /* Wait for a reply, return the good/bad news... */
6365   W (ret);
6366   return ret;
6367 }
6368
6369 static int
6370 api_sw_interface_set_rx_mode (vat_main_t * vam)
6371 {
6372   unformat_input_t *i = vam->input;
6373   vl_api_sw_interface_set_rx_mode_t *mp;
6374   u32 sw_if_index;
6375   u8 sw_if_index_set = 0;
6376   int ret;
6377   u8 queue_id_valid = 0;
6378   u32 queue_id;
6379   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6380
6381   /* Parse args required to build the message */
6382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6383     {
6384       if (unformat (i, "queue %d", &queue_id))
6385         queue_id_valid = 1;
6386       else if (unformat (i, "polling"))
6387         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6388       else if (unformat (i, "interrupt"))
6389         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6390       else if (unformat (i, "adaptive"))
6391         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6392       else
6393         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6394         sw_if_index_set = 1;
6395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6396         sw_if_index_set = 1;
6397       else
6398         break;
6399     }
6400
6401   if (sw_if_index_set == 0)
6402     {
6403       errmsg ("missing interface name or sw_if_index");
6404       return -99;
6405     }
6406   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6407     {
6408       errmsg ("missing rx-mode");
6409       return -99;
6410     }
6411
6412   /* Construct the API message */
6413   M (SW_INTERFACE_SET_RX_MODE, mp);
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->mode = mode;
6416   mp->queue_id_valid = queue_id_valid;
6417   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6418
6419   /* send it... */
6420   S (mp);
6421
6422   /* Wait for a reply, return the good/bad news... */
6423   W (ret);
6424   return ret;
6425 }
6426
6427 static int
6428 api_sw_interface_clear_stats (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_sw_interface_clear_stats_t *mp;
6432   u32 sw_if_index;
6433   u8 sw_if_index_set = 0;
6434   int ret;
6435
6436   /* Parse args required to build the message */
6437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6438     {
6439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6440         sw_if_index_set = 1;
6441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6442         sw_if_index_set = 1;
6443       else
6444         break;
6445     }
6446
6447   /* Construct the API message */
6448   M (SW_INTERFACE_CLEAR_STATS, mp);
6449
6450   if (sw_if_index_set == 1)
6451     mp->sw_if_index = ntohl (sw_if_index);
6452   else
6453     mp->sw_if_index = ~0;
6454
6455   /* send it... */
6456   S (mp);
6457
6458   /* Wait for a reply, return the good/bad news... */
6459   W (ret);
6460   return ret;
6461 }
6462
6463 static int
6464 api_sw_interface_add_del_address (vat_main_t * vam)
6465 {
6466   unformat_input_t *i = vam->input;
6467   vl_api_sw_interface_add_del_address_t *mp;
6468   u32 sw_if_index;
6469   u8 sw_if_index_set = 0;
6470   u8 is_add = 1, del_all = 0;
6471   u32 address_length = 0;
6472   u8 v4_address_set = 0;
6473   u8 v6_address_set = 0;
6474   ip4_address_t v4address;
6475   ip6_address_t v6address;
6476   int ret;
6477
6478   /* Parse args required to build the message */
6479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6480     {
6481       if (unformat (i, "del-all"))
6482         del_all = 1;
6483       else if (unformat (i, "del"))
6484         is_add = 0;
6485       else
6486         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6489         sw_if_index_set = 1;
6490       else if (unformat (i, "%U/%d",
6491                          unformat_ip4_address, &v4address, &address_length))
6492         v4_address_set = 1;
6493       else if (unformat (i, "%U/%d",
6494                          unformat_ip6_address, &v6address, &address_length))
6495         v6_address_set = 1;
6496       else
6497         break;
6498     }
6499
6500   if (sw_if_index_set == 0)
6501     {
6502       errmsg ("missing interface name or sw_if_index");
6503       return -99;
6504     }
6505   if (v4_address_set && v6_address_set)
6506     {
6507       errmsg ("both v4 and v6 addresses set");
6508       return -99;
6509     }
6510   if (!v4_address_set && !v6_address_set && !del_all)
6511     {
6512       errmsg ("no addresses set");
6513       return -99;
6514     }
6515
6516   /* Construct the API message */
6517   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6518
6519   mp->sw_if_index = ntohl (sw_if_index);
6520   mp->is_add = is_add;
6521   mp->del_all = del_all;
6522   if (v6_address_set)
6523     {
6524       mp->is_ipv6 = 1;
6525       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6526     }
6527   else
6528     {
6529       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6530     }
6531   mp->address_length = address_length;
6532
6533   /* send it... */
6534   S (mp);
6535
6536   /* Wait for a reply, return good/bad news  */
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_sw_interface_set_mpls_enable_t *mp;
6546   u32 sw_if_index;
6547   u8 sw_if_index_set = 0;
6548   u8 enable = 1;
6549   int ret;
6550
6551   /* Parse args required to build the message */
6552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6553     {
6554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6555         sw_if_index_set = 1;
6556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6557         sw_if_index_set = 1;
6558       else if (unformat (i, "disable"))
6559         enable = 0;
6560       else if (unformat (i, "dis"))
6561         enable = 0;
6562       else
6563         break;
6564     }
6565
6566   if (sw_if_index_set == 0)
6567     {
6568       errmsg ("missing interface name or sw_if_index");
6569       return -99;
6570     }
6571
6572   /* Construct the API message */
6573   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6574
6575   mp->sw_if_index = ntohl (sw_if_index);
6576   mp->enable = enable;
6577
6578   /* send it... */
6579   S (mp);
6580
6581   /* Wait for a reply... */
6582   W (ret);
6583   return ret;
6584 }
6585
6586 static int
6587 api_sw_interface_set_table (vat_main_t * vam)
6588 {
6589   unformat_input_t *i = vam->input;
6590   vl_api_sw_interface_set_table_t *mp;
6591   u32 sw_if_index, vrf_id = 0;
6592   u8 sw_if_index_set = 0;
6593   u8 is_ipv6 = 0;
6594   int ret;
6595
6596   /* Parse args required to build the message */
6597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6598     {
6599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6600         sw_if_index_set = 1;
6601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6602         sw_if_index_set = 1;
6603       else if (unformat (i, "vrf %d", &vrf_id))
6604         ;
6605       else if (unformat (i, "ipv6"))
6606         is_ipv6 = 1;
6607       else
6608         break;
6609     }
6610
6611   if (sw_if_index_set == 0)
6612     {
6613       errmsg ("missing interface name or sw_if_index");
6614       return -99;
6615     }
6616
6617   /* Construct the API message */
6618   M (SW_INTERFACE_SET_TABLE, mp);
6619
6620   mp->sw_if_index = ntohl (sw_if_index);
6621   mp->is_ipv6 = is_ipv6;
6622   mp->vrf_id = ntohl (vrf_id);
6623
6624   /* send it... */
6625   S (mp);
6626
6627   /* Wait for a reply... */
6628   W (ret);
6629   return ret;
6630 }
6631
6632 static void vl_api_sw_interface_get_table_reply_t_handler
6633   (vl_api_sw_interface_get_table_reply_t * mp)
6634 {
6635   vat_main_t *vam = &vat_main;
6636
6637   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6638
6639   vam->retval = ntohl (mp->retval);
6640   vam->result_ready = 1;
6641
6642 }
6643
6644 static void vl_api_sw_interface_get_table_reply_t_handler_json
6645   (vl_api_sw_interface_get_table_reply_t * mp)
6646 {
6647   vat_main_t *vam = &vat_main;
6648   vat_json_node_t node;
6649
6650   vat_json_init_object (&node);
6651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6652   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6653
6654   vat_json_print (vam->ofp, &node);
6655   vat_json_free (&node);
6656
6657   vam->retval = ntohl (mp->retval);
6658   vam->result_ready = 1;
6659 }
6660
6661 static int
6662 api_sw_interface_get_table (vat_main_t * vam)
6663 {
6664   unformat_input_t *i = vam->input;
6665   vl_api_sw_interface_get_table_t *mp;
6666   u32 sw_if_index;
6667   u8 sw_if_index_set = 0;
6668   u8 is_ipv6 = 0;
6669   int ret;
6670
6671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6672     {
6673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6676         sw_if_index_set = 1;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   M (SW_INTERFACE_GET_TABLE, mp);
6690   mp->sw_if_index = htonl (sw_if_index);
6691   mp->is_ipv6 = is_ipv6;
6692
6693   S (mp);
6694   W (ret);
6695   return ret;
6696 }
6697
6698 static int
6699 api_sw_interface_set_vpath (vat_main_t * vam)
6700 {
6701   unformat_input_t *i = vam->input;
6702   vl_api_sw_interface_set_vpath_t *mp;
6703   u32 sw_if_index = 0;
6704   u8 sw_if_index_set = 0;
6705   u8 is_enable = 0;
6706   int ret;
6707
6708   /* Parse args required to build the message */
6709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6710     {
6711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6712         sw_if_index_set = 1;
6713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6714         sw_if_index_set = 1;
6715       else if (unformat (i, "enable"))
6716         is_enable = 1;
6717       else if (unformat (i, "disable"))
6718         is_enable = 0;
6719       else
6720         break;
6721     }
6722
6723   if (sw_if_index_set == 0)
6724     {
6725       errmsg ("missing interface name or sw_if_index");
6726       return -99;
6727     }
6728
6729   /* Construct the API message */
6730   M (SW_INTERFACE_SET_VPATH, mp);
6731
6732   mp->sw_if_index = ntohl (sw_if_index);
6733   mp->enable = is_enable;
6734
6735   /* send it... */
6736   S (mp);
6737
6738   /* Wait for a reply... */
6739   W (ret);
6740   return ret;
6741 }
6742
6743 static int
6744 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6748   u32 sw_if_index = 0;
6749   u8 sw_if_index_set = 0;
6750   u8 is_enable = 1;
6751   u8 is_ipv6 = 0;
6752   int ret;
6753
6754   /* Parse args required to build the message */
6755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6756     {
6757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6758         sw_if_index_set = 1;
6759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "enable"))
6762         is_enable = 1;
6763       else if (unformat (i, "disable"))
6764         is_enable = 0;
6765       else if (unformat (i, "ip4"))
6766         is_ipv6 = 0;
6767       else if (unformat (i, "ip6"))
6768         is_ipv6 = 1;
6769       else
6770         break;
6771     }
6772
6773   if (sw_if_index_set == 0)
6774     {
6775       errmsg ("missing interface name or sw_if_index");
6776       return -99;
6777     }
6778
6779   /* Construct the API message */
6780   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6781
6782   mp->sw_if_index = ntohl (sw_if_index);
6783   mp->enable = is_enable;
6784   mp->is_ipv6 = is_ipv6;
6785
6786   /* send it... */
6787   S (mp);
6788
6789   /* Wait for a reply... */
6790   W (ret);
6791   return ret;
6792 }
6793
6794 static int
6795 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6796 {
6797   unformat_input_t *i = vam->input;
6798   vl_api_sw_interface_set_geneve_bypass_t *mp;
6799   u32 sw_if_index = 0;
6800   u8 sw_if_index_set = 0;
6801   u8 is_enable = 1;
6802   u8 is_ipv6 = 0;
6803   int ret;
6804
6805   /* Parse args required to build the message */
6806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6807     {
6808       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6809         sw_if_index_set = 1;
6810       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6811         sw_if_index_set = 1;
6812       else if (unformat (i, "enable"))
6813         is_enable = 1;
6814       else if (unformat (i, "disable"))
6815         is_enable = 0;
6816       else if (unformat (i, "ip4"))
6817         is_ipv6 = 0;
6818       else if (unformat (i, "ip6"))
6819         is_ipv6 = 1;
6820       else
6821         break;
6822     }
6823
6824   if (sw_if_index_set == 0)
6825     {
6826       errmsg ("missing interface name or sw_if_index");
6827       return -99;
6828     }
6829
6830   /* Construct the API message */
6831   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6832
6833   mp->sw_if_index = ntohl (sw_if_index);
6834   mp->enable = is_enable;
6835   mp->is_ipv6 = is_ipv6;
6836
6837   /* send it... */
6838   S (mp);
6839
6840   /* Wait for a reply... */
6841   W (ret);
6842   return ret;
6843 }
6844
6845 static int
6846 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6847 {
6848   unformat_input_t *i = vam->input;
6849   vl_api_sw_interface_set_l2_xconnect_t *mp;
6850   u32 rx_sw_if_index;
6851   u8 rx_sw_if_index_set = 0;
6852   u32 tx_sw_if_index;
6853   u8 tx_sw_if_index_set = 0;
6854   u8 enable = 1;
6855   int ret;
6856
6857   /* Parse args required to build the message */
6858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6859     {
6860       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6861         rx_sw_if_index_set = 1;
6862       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6863         tx_sw_if_index_set = 1;
6864       else if (unformat (i, "rx"))
6865         {
6866           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6867             {
6868               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6869                             &rx_sw_if_index))
6870                 rx_sw_if_index_set = 1;
6871             }
6872           else
6873             break;
6874         }
6875       else if (unformat (i, "tx"))
6876         {
6877           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6878             {
6879               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6880                             &tx_sw_if_index))
6881                 tx_sw_if_index_set = 1;
6882             }
6883           else
6884             break;
6885         }
6886       else if (unformat (i, "enable"))
6887         enable = 1;
6888       else if (unformat (i, "disable"))
6889         enable = 0;
6890       else
6891         break;
6892     }
6893
6894   if (rx_sw_if_index_set == 0)
6895     {
6896       errmsg ("missing rx interface name or rx_sw_if_index");
6897       return -99;
6898     }
6899
6900   if (enable && (tx_sw_if_index_set == 0))
6901     {
6902       errmsg ("missing tx interface name or tx_sw_if_index");
6903       return -99;
6904     }
6905
6906   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6907
6908   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6909   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6910   mp->enable = enable;
6911
6912   S (mp);
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_bridge_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 bd_id;
6925   u8 bd_id_set = 0;
6926   u8 bvi = 0;
6927   u32 shg = 0;
6928   u8 enable = 1;
6929   int ret;
6930
6931   /* Parse args required to build the message */
6932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6933     {
6934       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6935         rx_sw_if_index_set = 1;
6936       else if (unformat (i, "bd_id %d", &bd_id))
6937         bd_id_set = 1;
6938       else
6939         if (unformat
6940             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6941         rx_sw_if_index_set = 1;
6942       else if (unformat (i, "shg %d", &shg))
6943         ;
6944       else if (unformat (i, "bvi"))
6945         bvi = 1;
6946       else if (unformat (i, "enable"))
6947         enable = 1;
6948       else if (unformat (i, "disable"))
6949         enable = 0;
6950       else
6951         break;
6952     }
6953
6954   if (rx_sw_if_index_set == 0)
6955     {
6956       errmsg ("missing rx interface name or sw_if_index");
6957       return -99;
6958     }
6959
6960   if (enable && (bd_id_set == 0))
6961     {
6962       errmsg ("missing bridge domain");
6963       return -99;
6964     }
6965
6966   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6967
6968   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6969   mp->bd_id = ntohl (bd_id);
6970   mp->shg = (u8) shg;
6971   mp->bvi = bvi;
6972   mp->enable = enable;
6973
6974   S (mp);
6975   W (ret);
6976   return ret;
6977 }
6978
6979 static int
6980 api_bridge_domain_dump (vat_main_t * vam)
6981 {
6982   unformat_input_t *i = vam->input;
6983   vl_api_bridge_domain_dump_t *mp;
6984   vl_api_control_ping_t *mp_ping;
6985   u32 bd_id = ~0;
6986   int ret;
6987
6988   /* Parse args required to build the message */
6989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6990     {
6991       if (unformat (i, "bd_id %d", &bd_id))
6992         ;
6993       else
6994         break;
6995     }
6996
6997   M (BRIDGE_DOMAIN_DUMP, mp);
6998   mp->bd_id = ntohl (bd_id);
6999   S (mp);
7000
7001   /* Use a control ping for synchronization */
7002   MPING (CONTROL_PING, mp_ping);
7003   S (mp_ping);
7004
7005   W (ret);
7006   return ret;
7007 }
7008
7009 static int
7010 api_bridge_domain_add_del (vat_main_t * vam)
7011 {
7012   unformat_input_t *i = vam->input;
7013   vl_api_bridge_domain_add_del_t *mp;
7014   u32 bd_id = ~0;
7015   u8 is_add = 1;
7016   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7017   u8 *bd_tag = NULL;
7018   u32 mac_age = 0;
7019   int ret;
7020
7021   /* Parse args required to build the message */
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "bd_id %d", &bd_id))
7025         ;
7026       else if (unformat (i, "flood %d", &flood))
7027         ;
7028       else if (unformat (i, "uu-flood %d", &uu_flood))
7029         ;
7030       else if (unformat (i, "forward %d", &forward))
7031         ;
7032       else if (unformat (i, "learn %d", &learn))
7033         ;
7034       else if (unformat (i, "arp-term %d", &arp_term))
7035         ;
7036       else if (unformat (i, "mac-age %d", &mac_age))
7037         ;
7038       else if (unformat (i, "bd-tag %s", &bd_tag))
7039         ;
7040       else if (unformat (i, "del"))
7041         {
7042           is_add = 0;
7043           flood = uu_flood = forward = learn = 0;
7044         }
7045       else
7046         break;
7047     }
7048
7049   if (bd_id == ~0)
7050     {
7051       errmsg ("missing bridge domain");
7052       ret = -99;
7053       goto done;
7054     }
7055
7056   if (mac_age > 255)
7057     {
7058       errmsg ("mac age must be less than 256 ");
7059       ret = -99;
7060       goto done;
7061     }
7062
7063   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7064     {
7065       errmsg ("bd-tag cannot be longer than 63");
7066       ret = -99;
7067       goto done;
7068     }
7069
7070   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7071
7072   mp->bd_id = ntohl (bd_id);
7073   mp->flood = flood;
7074   mp->uu_flood = uu_flood;
7075   mp->forward = forward;
7076   mp->learn = learn;
7077   mp->arp_term = arp_term;
7078   mp->is_add = is_add;
7079   mp->mac_age = (u8) mac_age;
7080   if (bd_tag)
7081     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7082
7083   S (mp);
7084   W (ret);
7085
7086 done:
7087   vec_free (bd_tag);
7088   return ret;
7089 }
7090
7091 static int
7092 api_l2fib_flush_bd (vat_main_t * vam)
7093 {
7094   unformat_input_t *i = vam->input;
7095   vl_api_l2fib_flush_bd_t *mp;
7096   u32 bd_id = ~0;
7097   int ret;
7098
7099   /* Parse args required to build the message */
7100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7101     {
7102       if (unformat (i, "bd_id %d", &bd_id));
7103       else
7104         break;
7105     }
7106
7107   if (bd_id == ~0)
7108     {
7109       errmsg ("missing bridge domain");
7110       return -99;
7111     }
7112
7113   M (L2FIB_FLUSH_BD, mp);
7114
7115   mp->bd_id = htonl (bd_id);
7116
7117   S (mp);
7118   W (ret);
7119   return ret;
7120 }
7121
7122 static int
7123 api_l2fib_flush_int (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_l2fib_flush_int_t *mp;
7127   u32 sw_if_index = ~0;
7128   int ret;
7129
7130   /* Parse args required to build the message */
7131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7132     {
7133       if (unformat (i, "sw_if_index %d", &sw_if_index));
7134       else
7135         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7136       else
7137         break;
7138     }
7139
7140   if (sw_if_index == ~0)
7141     {
7142       errmsg ("missing interface name or sw_if_index");
7143       return -99;
7144     }
7145
7146   M (L2FIB_FLUSH_INT, mp);
7147
7148   mp->sw_if_index = ntohl (sw_if_index);
7149
7150   S (mp);
7151   W (ret);
7152   return ret;
7153 }
7154
7155 static int
7156 api_l2fib_add_del (vat_main_t * vam)
7157 {
7158   unformat_input_t *i = vam->input;
7159   vl_api_l2fib_add_del_t *mp;
7160   f64 timeout;
7161   u8 mac[6] = { 0 };
7162   u8 mac_set = 0;
7163   u32 bd_id;
7164   u8 bd_id_set = 0;
7165   u32 sw_if_index = ~0;
7166   u8 sw_if_index_set = 0;
7167   u8 is_add = 1;
7168   u8 static_mac = 0;
7169   u8 filter_mac = 0;
7170   u8 bvi_mac = 0;
7171   int count = 1;
7172   f64 before = 0;
7173   int j;
7174
7175   /* Parse args required to build the message */
7176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7177     {
7178       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7179         mac_set = 1;
7180       else if (unformat (i, "bd_id %d", &bd_id))
7181         bd_id_set = 1;
7182       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7183         sw_if_index_set = 1;
7184       else if (unformat (i, "sw_if"))
7185         {
7186           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7187             {
7188               if (unformat
7189                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7190                 sw_if_index_set = 1;
7191             }
7192           else
7193             break;
7194         }
7195       else if (unformat (i, "static"))
7196         static_mac = 1;
7197       else if (unformat (i, "filter"))
7198         {
7199           filter_mac = 1;
7200           static_mac = 1;
7201         }
7202       else if (unformat (i, "bvi"))
7203         {
7204           bvi_mac = 1;
7205           static_mac = 1;
7206         }
7207       else if (unformat (i, "del"))
7208         is_add = 0;
7209       else if (unformat (i, "count %d", &count))
7210         ;
7211       else
7212         break;
7213     }
7214
7215   if (mac_set == 0)
7216     {
7217       errmsg ("missing mac address");
7218       return -99;
7219     }
7220
7221   if (bd_id_set == 0)
7222     {
7223       errmsg ("missing bridge domain");
7224       return -99;
7225     }
7226
7227   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7228     {
7229       errmsg ("missing interface name or sw_if_index");
7230       return -99;
7231     }
7232
7233   if (count > 1)
7234     {
7235       /* Turn on async mode */
7236       vam->async_mode = 1;
7237       vam->async_errors = 0;
7238       before = vat_time_now (vam);
7239     }
7240
7241   for (j = 0; j < count; j++)
7242     {
7243       M (L2FIB_ADD_DEL, mp);
7244
7245       clib_memcpy (mp->mac, mac, 6);
7246       mp->bd_id = ntohl (bd_id);
7247       mp->is_add = is_add;
7248
7249       if (is_add)
7250         {
7251           mp->sw_if_index = ntohl (sw_if_index);
7252           mp->static_mac = static_mac;
7253           mp->filter_mac = filter_mac;
7254           mp->bvi_mac = bvi_mac;
7255         }
7256       increment_mac_address (mac);
7257       /* send it... */
7258       S (mp);
7259     }
7260
7261   if (count > 1)
7262     {
7263       vl_api_control_ping_t *mp_ping;
7264       f64 after;
7265
7266       /* Shut off async mode */
7267       vam->async_mode = 0;
7268
7269       MPING (CONTROL_PING, mp_ping);
7270       S (mp_ping);
7271
7272       timeout = vat_time_now (vam) + 1.0;
7273       while (vat_time_now (vam) < timeout)
7274         if (vam->result_ready == 1)
7275           goto out;
7276       vam->retval = -99;
7277
7278     out:
7279       if (vam->retval == -99)
7280         errmsg ("timeout");
7281
7282       if (vam->async_errors > 0)
7283         {
7284           errmsg ("%d asynchronous errors", vam->async_errors);
7285           vam->retval = -98;
7286         }
7287       vam->async_errors = 0;
7288       after = vat_time_now (vam);
7289
7290       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7291              count, after - before, count / (after - before));
7292     }
7293   else
7294     {
7295       int ret;
7296
7297       /* Wait for a reply... */
7298       W (ret);
7299       return ret;
7300     }
7301   /* Return the good/bad news */
7302   return (vam->retval);
7303 }
7304
7305 static int
7306 api_bridge_domain_set_mac_age (vat_main_t * vam)
7307 {
7308   unformat_input_t *i = vam->input;
7309   vl_api_bridge_domain_set_mac_age_t *mp;
7310   u32 bd_id = ~0;
7311   u32 mac_age = 0;
7312   int ret;
7313
7314   /* Parse args required to build the message */
7315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7316     {
7317       if (unformat (i, "bd_id %d", &bd_id));
7318       else if (unformat (i, "mac-age %d", &mac_age));
7319       else
7320         break;
7321     }
7322
7323   if (bd_id == ~0)
7324     {
7325       errmsg ("missing bridge domain");
7326       return -99;
7327     }
7328
7329   if (mac_age > 255)
7330     {
7331       errmsg ("mac age must be less than 256 ");
7332       return -99;
7333     }
7334
7335   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7336
7337   mp->bd_id = htonl (bd_id);
7338   mp->mac_age = (u8) mac_age;
7339
7340   S (mp);
7341   W (ret);
7342   return ret;
7343 }
7344
7345 static int
7346 api_l2_flags (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_l2_flags_t *mp;
7350   u32 sw_if_index;
7351   u32 flags = 0;
7352   u8 sw_if_index_set = 0;
7353   u8 is_set = 0;
7354   int ret;
7355
7356   /* Parse args required to build the message */
7357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7358     {
7359       if (unformat (i, "sw_if_index %d", &sw_if_index))
7360         sw_if_index_set = 1;
7361       else if (unformat (i, "sw_if"))
7362         {
7363           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7364             {
7365               if (unformat
7366                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7367                 sw_if_index_set = 1;
7368             }
7369           else
7370             break;
7371         }
7372       else if (unformat (i, "learn"))
7373         flags |= L2_LEARN;
7374       else if (unformat (i, "forward"))
7375         flags |= L2_FWD;
7376       else if (unformat (i, "flood"))
7377         flags |= L2_FLOOD;
7378       else if (unformat (i, "uu-flood"))
7379         flags |= L2_UU_FLOOD;
7380       else if (unformat (i, "arp-term"))
7381         flags |= L2_ARP_TERM;
7382       else if (unformat (i, "off"))
7383         is_set = 0;
7384       else if (unformat (i, "disable"))
7385         is_set = 0;
7386       else
7387         break;
7388     }
7389
7390   if (sw_if_index_set == 0)
7391     {
7392       errmsg ("missing interface name or sw_if_index");
7393       return -99;
7394     }
7395
7396   M (L2_FLAGS, mp);
7397
7398   mp->sw_if_index = ntohl (sw_if_index);
7399   mp->feature_bitmap = ntohl (flags);
7400   mp->is_set = is_set;
7401
7402   S (mp);
7403   W (ret);
7404   return ret;
7405 }
7406
7407 static int
7408 api_bridge_flags (vat_main_t * vam)
7409 {
7410   unformat_input_t *i = vam->input;
7411   vl_api_bridge_flags_t *mp;
7412   u32 bd_id;
7413   u8 bd_id_set = 0;
7414   u8 is_set = 1;
7415   u32 flags = 0;
7416   int ret;
7417
7418   /* Parse args required to build the message */
7419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7420     {
7421       if (unformat (i, "bd_id %d", &bd_id))
7422         bd_id_set = 1;
7423       else if (unformat (i, "learn"))
7424         flags |= L2_LEARN;
7425       else if (unformat (i, "forward"))
7426         flags |= L2_FWD;
7427       else if (unformat (i, "flood"))
7428         flags |= L2_FLOOD;
7429       else if (unformat (i, "uu-flood"))
7430         flags |= L2_UU_FLOOD;
7431       else if (unformat (i, "arp-term"))
7432         flags |= L2_ARP_TERM;
7433       else if (unformat (i, "off"))
7434         is_set = 0;
7435       else if (unformat (i, "disable"))
7436         is_set = 0;
7437       else
7438         break;
7439     }
7440
7441   if (bd_id_set == 0)
7442     {
7443       errmsg ("missing bridge domain");
7444       return -99;
7445     }
7446
7447   M (BRIDGE_FLAGS, mp);
7448
7449   mp->bd_id = ntohl (bd_id);
7450   mp->feature_bitmap = ntohl (flags);
7451   mp->is_set = is_set;
7452
7453   S (mp);
7454   W (ret);
7455   return ret;
7456 }
7457
7458 static int
7459 api_bd_ip_mac_add_del (vat_main_t * vam)
7460 {
7461   unformat_input_t *i = vam->input;
7462   vl_api_bd_ip_mac_add_del_t *mp;
7463   u32 bd_id;
7464   u8 is_ipv6 = 0;
7465   u8 is_add = 1;
7466   u8 bd_id_set = 0;
7467   u8 ip_set = 0;
7468   u8 mac_set = 0;
7469   ip4_address_t v4addr;
7470   ip6_address_t v6addr;
7471   u8 macaddr[6];
7472   int ret;
7473
7474
7475   /* Parse args required to build the message */
7476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7477     {
7478       if (unformat (i, "bd_id %d", &bd_id))
7479         {
7480           bd_id_set++;
7481         }
7482       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7483         {
7484           ip_set++;
7485         }
7486       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7487         {
7488           ip_set++;
7489           is_ipv6++;
7490         }
7491       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7492         {
7493           mac_set++;
7494         }
7495       else if (unformat (i, "del"))
7496         is_add = 0;
7497       else
7498         break;
7499     }
7500
7501   if (bd_id_set == 0)
7502     {
7503       errmsg ("missing bridge domain");
7504       return -99;
7505     }
7506   else if (ip_set == 0)
7507     {
7508       errmsg ("missing IP address");
7509       return -99;
7510     }
7511   else if (mac_set == 0)
7512     {
7513       errmsg ("missing MAC address");
7514       return -99;
7515     }
7516
7517   M (BD_IP_MAC_ADD_DEL, mp);
7518
7519   mp->bd_id = ntohl (bd_id);
7520   mp->is_ipv6 = is_ipv6;
7521   mp->is_add = is_add;
7522   if (is_ipv6)
7523     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7524   else
7525     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7526   clib_memcpy (mp->mac_address, macaddr, 6);
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_tap_connect (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_tap_connect_t *mp;
7537   u8 mac_address[6];
7538   u8 random_mac = 1;
7539   u8 name_set = 0;
7540   u8 *tap_name;
7541   u8 *tag = 0;
7542   ip4_address_t ip4_address;
7543   u32 ip4_mask_width;
7544   int ip4_address_set = 0;
7545   ip6_address_t ip6_address;
7546   u32 ip6_mask_width;
7547   int ip6_address_set = 0;
7548   int ret;
7549
7550   memset (mac_address, 0, sizeof (mac_address));
7551
7552   /* Parse args required to build the message */
7553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7554     {
7555       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7556         {
7557           random_mac = 0;
7558         }
7559       else if (unformat (i, "random-mac"))
7560         random_mac = 1;
7561       else if (unformat (i, "tapname %s", &tap_name))
7562         name_set = 1;
7563       else if (unformat (i, "tag %s", &tag))
7564         ;
7565       else if (unformat (i, "address %U/%d",
7566                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7567         ip4_address_set = 1;
7568       else if (unformat (i, "address %U/%d",
7569                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7570         ip6_address_set = 1;
7571       else
7572         break;
7573     }
7574
7575   if (name_set == 0)
7576     {
7577       errmsg ("missing tap name");
7578       return -99;
7579     }
7580   if (vec_len (tap_name) > 63)
7581     {
7582       errmsg ("tap name too long");
7583       return -99;
7584     }
7585   vec_add1 (tap_name, 0);
7586
7587   if (vec_len (tag) > 63)
7588     {
7589       errmsg ("tag too long");
7590       return -99;
7591     }
7592
7593   /* Construct the API message */
7594   M (TAP_CONNECT, mp);
7595
7596   mp->use_random_mac = random_mac;
7597   clib_memcpy (mp->mac_address, mac_address, 6);
7598   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7599   if (tag)
7600     clib_memcpy (mp->tag, tag, vec_len (tag));
7601
7602   if (ip4_address_set)
7603     {
7604       mp->ip4_address_set = 1;
7605       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7606       mp->ip4_mask_width = ip4_mask_width;
7607     }
7608   if (ip6_address_set)
7609     {
7610       mp->ip6_address_set = 1;
7611       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7612       mp->ip6_mask_width = ip6_mask_width;
7613     }
7614
7615   vec_free (tap_name);
7616   vec_free (tag);
7617
7618   /* send it... */
7619   S (mp);
7620
7621   /* Wait for a reply... */
7622   W (ret);
7623   return ret;
7624 }
7625
7626 static int
7627 api_tap_modify (vat_main_t * vam)
7628 {
7629   unformat_input_t *i = vam->input;
7630   vl_api_tap_modify_t *mp;
7631   u8 mac_address[6];
7632   u8 random_mac = 1;
7633   u8 name_set = 0;
7634   u8 *tap_name;
7635   u32 sw_if_index = ~0;
7636   u8 sw_if_index_set = 0;
7637   int ret;
7638
7639   memset (mac_address, 0, sizeof (mac_address));
7640
7641   /* Parse args required to build the message */
7642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643     {
7644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7645         sw_if_index_set = 1;
7646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7647         sw_if_index_set = 1;
7648       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7649         {
7650           random_mac = 0;
7651         }
7652       else if (unformat (i, "random-mac"))
7653         random_mac = 1;
7654       else if (unformat (i, "tapname %s", &tap_name))
7655         name_set = 1;
7656       else
7657         break;
7658     }
7659
7660   if (sw_if_index_set == 0)
7661     {
7662       errmsg ("missing vpp interface name");
7663       return -99;
7664     }
7665   if (name_set == 0)
7666     {
7667       errmsg ("missing tap name");
7668       return -99;
7669     }
7670   if (vec_len (tap_name) > 63)
7671     {
7672       errmsg ("tap name too long");
7673     }
7674   vec_add1 (tap_name, 0);
7675
7676   /* Construct the API message */
7677   M (TAP_MODIFY, mp);
7678
7679   mp->use_random_mac = random_mac;
7680   mp->sw_if_index = ntohl (sw_if_index);
7681   clib_memcpy (mp->mac_address, mac_address, 6);
7682   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7683   vec_free (tap_name);
7684
7685   /* send it... */
7686   S (mp);
7687
7688   /* Wait for a reply... */
7689   W (ret);
7690   return ret;
7691 }
7692
7693 static int
7694 api_tap_delete (vat_main_t * vam)
7695 {
7696   unformat_input_t *i = vam->input;
7697   vl_api_tap_delete_t *mp;
7698   u32 sw_if_index = ~0;
7699   u8 sw_if_index_set = 0;
7700   int ret;
7701
7702   /* Parse args required to build the message */
7703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7704     {
7705       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7706         sw_if_index_set = 1;
7707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7708         sw_if_index_set = 1;
7709       else
7710         break;
7711     }
7712
7713   if (sw_if_index_set == 0)
7714     {
7715       errmsg ("missing vpp interface name");
7716       return -99;
7717     }
7718
7719   /* Construct the API message */
7720   M (TAP_DELETE, mp);
7721
7722   mp->sw_if_index = ntohl (sw_if_index);
7723
7724   /* send it... */
7725   S (mp);
7726
7727   /* Wait for a reply... */
7728   W (ret);
7729   return ret;
7730 }
7731
7732 static int
7733 api_ip_table_add_del (vat_main_t * vam)
7734 {
7735   unformat_input_t *i = vam->input;
7736   vl_api_ip_table_add_del_t *mp;
7737   u32 table_id = ~0;
7738   u8 is_ipv6 = 0;
7739   u8 is_add = 1;
7740   int ret = 0;
7741
7742   /* Parse args required to build the message */
7743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7744     {
7745       if (unformat (i, "ipv6"))
7746         is_ipv6 = 1;
7747       else if (unformat (i, "del"))
7748         is_add = 0;
7749       else if (unformat (i, "add"))
7750         is_add = 1;
7751       else if (unformat (i, "table %d", &table_id))
7752         ;
7753       else
7754         {
7755           clib_warning ("parse error '%U'", format_unformat_error, i);
7756           return -99;
7757         }
7758     }
7759
7760   if (~0 == table_id)
7761     {
7762       errmsg ("missing table-ID");
7763       return -99;
7764     }
7765
7766   /* Construct the API message */
7767   M (IP_TABLE_ADD_DEL, mp);
7768
7769   mp->table_id = ntohl (table_id);
7770   mp->is_ipv6 = is_ipv6;
7771   mp->is_add = is_add;
7772
7773   /* send it... */
7774   S (mp);
7775
7776   /* Wait for a reply... */
7777   W (ret);
7778
7779   return ret;
7780 }
7781
7782 static int
7783 api_ip_add_del_route (vat_main_t * vam)
7784 {
7785   unformat_input_t *i = vam->input;
7786   vl_api_ip_add_del_route_t *mp;
7787   u32 sw_if_index = ~0, vrf_id = 0;
7788   u8 is_ipv6 = 0;
7789   u8 is_local = 0, is_drop = 0;
7790   u8 is_unreach = 0, is_prohibit = 0;
7791   u8 create_vrf_if_needed = 0;
7792   u8 is_add = 1;
7793   u32 next_hop_weight = 1;
7794   u8 is_multipath = 0;
7795   u8 address_set = 0;
7796   u8 address_length_set = 0;
7797   u32 next_hop_table_id = 0;
7798   u32 resolve_attempts = 0;
7799   u32 dst_address_length = 0;
7800   u8 next_hop_set = 0;
7801   ip4_address_t v4_dst_address, v4_next_hop_address;
7802   ip6_address_t v6_dst_address, v6_next_hop_address;
7803   int count = 1;
7804   int j;
7805   f64 before = 0;
7806   u32 random_add_del = 0;
7807   u32 *random_vector = 0;
7808   uword *random_hash;
7809   u32 random_seed = 0xdeaddabe;
7810   u32 classify_table_index = ~0;
7811   u8 is_classify = 0;
7812   u8 resolve_host = 0, resolve_attached = 0;
7813   mpls_label_t *next_hop_out_label_stack = NULL;
7814   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7815   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7816
7817   /* Parse args required to build the message */
7818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7819     {
7820       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7821         ;
7822       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7823         ;
7824       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7825         {
7826           address_set = 1;
7827           is_ipv6 = 0;
7828         }
7829       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7830         {
7831           address_set = 1;
7832           is_ipv6 = 1;
7833         }
7834       else if (unformat (i, "/%d", &dst_address_length))
7835         {
7836           address_length_set = 1;
7837         }
7838
7839       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7840                                          &v4_next_hop_address))
7841         {
7842           next_hop_set = 1;
7843         }
7844       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7845                                          &v6_next_hop_address))
7846         {
7847           next_hop_set = 1;
7848         }
7849       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7850         ;
7851       else if (unformat (i, "weight %d", &next_hop_weight))
7852         ;
7853       else if (unformat (i, "drop"))
7854         {
7855           is_drop = 1;
7856         }
7857       else if (unformat (i, "null-send-unreach"))
7858         {
7859           is_unreach = 1;
7860         }
7861       else if (unformat (i, "null-send-prohibit"))
7862         {
7863           is_prohibit = 1;
7864         }
7865       else if (unformat (i, "local"))
7866         {
7867           is_local = 1;
7868         }
7869       else if (unformat (i, "classify %d", &classify_table_index))
7870         {
7871           is_classify = 1;
7872         }
7873       else if (unformat (i, "del"))
7874         is_add = 0;
7875       else if (unformat (i, "add"))
7876         is_add = 1;
7877       else if (unformat (i, "resolve-via-host"))
7878         resolve_host = 1;
7879       else if (unformat (i, "resolve-via-attached"))
7880         resolve_attached = 1;
7881       else if (unformat (i, "multipath"))
7882         is_multipath = 1;
7883       else if (unformat (i, "vrf %d", &vrf_id))
7884         ;
7885       else if (unformat (i, "create-vrf"))
7886         create_vrf_if_needed = 1;
7887       else if (unformat (i, "count %d", &count))
7888         ;
7889       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7890         ;
7891       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7892         ;
7893       else if (unformat (i, "out-label %d", &next_hop_out_label))
7894         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7895       else if (unformat (i, "via-label %d", &next_hop_via_label))
7896         ;
7897       else if (unformat (i, "random"))
7898         random_add_del = 1;
7899       else if (unformat (i, "seed %d", &random_seed))
7900         ;
7901       else
7902         {
7903           clib_warning ("parse error '%U'", format_unformat_error, i);
7904           return -99;
7905         }
7906     }
7907
7908   if (!next_hop_set && !is_drop && !is_local &&
7909       !is_classify && !is_unreach && !is_prohibit &&
7910       MPLS_LABEL_INVALID == next_hop_via_label)
7911     {
7912       errmsg
7913         ("next hop / local / drop / unreach / prohibit / classify not set");
7914       return -99;
7915     }
7916
7917   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7918     {
7919       errmsg ("next hop and next-hop via label set");
7920       return -99;
7921     }
7922   if (address_set == 0)
7923     {
7924       errmsg ("missing addresses");
7925       return -99;
7926     }
7927
7928   if (address_length_set == 0)
7929     {
7930       errmsg ("missing address length");
7931       return -99;
7932     }
7933
7934   /* Generate a pile of unique, random routes */
7935   if (random_add_del)
7936     {
7937       u32 this_random_address;
7938       random_hash = hash_create (count, sizeof (uword));
7939
7940       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7941       for (j = 0; j <= count; j++)
7942         {
7943           do
7944             {
7945               this_random_address = random_u32 (&random_seed);
7946               this_random_address =
7947                 clib_host_to_net_u32 (this_random_address);
7948             }
7949           while (hash_get (random_hash, this_random_address));
7950           vec_add1 (random_vector, this_random_address);
7951           hash_set (random_hash, this_random_address, 1);
7952         }
7953       hash_free (random_hash);
7954       v4_dst_address.as_u32 = random_vector[0];
7955     }
7956
7957   if (count > 1)
7958     {
7959       /* Turn on async mode */
7960       vam->async_mode = 1;
7961       vam->async_errors = 0;
7962       before = vat_time_now (vam);
7963     }
7964
7965   for (j = 0; j < count; j++)
7966     {
7967       /* Construct the API message */
7968       M2 (IP_ADD_DEL_ROUTE, mp,
7969           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7970
7971       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7972       mp->table_id = ntohl (vrf_id);
7973       mp->create_vrf_if_needed = create_vrf_if_needed;
7974
7975       mp->is_add = is_add;
7976       mp->is_drop = is_drop;
7977       mp->is_unreach = is_unreach;
7978       mp->is_prohibit = is_prohibit;
7979       mp->is_ipv6 = is_ipv6;
7980       mp->is_local = is_local;
7981       mp->is_classify = is_classify;
7982       mp->is_multipath = is_multipath;
7983       mp->is_resolve_host = resolve_host;
7984       mp->is_resolve_attached = resolve_attached;
7985       mp->next_hop_weight = next_hop_weight;
7986       mp->dst_address_length = dst_address_length;
7987       mp->next_hop_table_id = ntohl (next_hop_table_id);
7988       mp->classify_table_index = ntohl (classify_table_index);
7989       mp->next_hop_via_label = ntohl (next_hop_via_label);
7990       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7991       if (0 != mp->next_hop_n_out_labels)
7992         {
7993           memcpy (mp->next_hop_out_label_stack,
7994                   next_hop_out_label_stack,
7995                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7996           vec_free (next_hop_out_label_stack);
7997         }
7998
7999       if (is_ipv6)
8000         {
8001           clib_memcpy (mp->dst_address, &v6_dst_address,
8002                        sizeof (v6_dst_address));
8003           if (next_hop_set)
8004             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8005                          sizeof (v6_next_hop_address));
8006           increment_v6_address (&v6_dst_address);
8007         }
8008       else
8009         {
8010           clib_memcpy (mp->dst_address, &v4_dst_address,
8011                        sizeof (v4_dst_address));
8012           if (next_hop_set)
8013             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8014                          sizeof (v4_next_hop_address));
8015           if (random_add_del)
8016             v4_dst_address.as_u32 = random_vector[j + 1];
8017           else
8018             increment_v4_address (&v4_dst_address);
8019         }
8020       /* send it... */
8021       S (mp);
8022       /* If we receive SIGTERM, stop now... */
8023       if (vam->do_exit)
8024         break;
8025     }
8026
8027   /* When testing multiple add/del ops, use a control-ping to sync */
8028   if (count > 1)
8029     {
8030       vl_api_control_ping_t *mp_ping;
8031       f64 after;
8032       f64 timeout;
8033
8034       /* Shut off async mode */
8035       vam->async_mode = 0;
8036
8037       MPING (CONTROL_PING, mp_ping);
8038       S (mp_ping);
8039
8040       timeout = vat_time_now (vam) + 1.0;
8041       while (vat_time_now (vam) < timeout)
8042         if (vam->result_ready == 1)
8043           goto out;
8044       vam->retval = -99;
8045
8046     out:
8047       if (vam->retval == -99)
8048         errmsg ("timeout");
8049
8050       if (vam->async_errors > 0)
8051         {
8052           errmsg ("%d asynchronous errors", vam->async_errors);
8053           vam->retval = -98;
8054         }
8055       vam->async_errors = 0;
8056       after = vat_time_now (vam);
8057
8058       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8059       if (j > 0)
8060         count = j;
8061
8062       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8063              count, after - before, count / (after - before));
8064     }
8065   else
8066     {
8067       int ret;
8068
8069       /* Wait for a reply... */
8070       W (ret);
8071       return ret;
8072     }
8073
8074   /* Return the good/bad news */
8075   return (vam->retval);
8076 }
8077
8078 static int
8079 api_ip_mroute_add_del (vat_main_t * vam)
8080 {
8081   unformat_input_t *i = vam->input;
8082   vl_api_ip_mroute_add_del_t *mp;
8083   u32 sw_if_index = ~0, vrf_id = 0;
8084   u8 is_ipv6 = 0;
8085   u8 is_local = 0;
8086   u8 create_vrf_if_needed = 0;
8087   u8 is_add = 1;
8088   u8 address_set = 0;
8089   u32 grp_address_length = 0;
8090   ip4_address_t v4_grp_address, v4_src_address;
8091   ip6_address_t v6_grp_address, v6_src_address;
8092   mfib_itf_flags_t iflags = 0;
8093   mfib_entry_flags_t eflags = 0;
8094   int ret;
8095
8096   /* Parse args required to build the message */
8097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8098     {
8099       if (unformat (i, "sw_if_index %d", &sw_if_index))
8100         ;
8101       else if (unformat (i, "%U %U",
8102                          unformat_ip4_address, &v4_src_address,
8103                          unformat_ip4_address, &v4_grp_address))
8104         {
8105           grp_address_length = 64;
8106           address_set = 1;
8107           is_ipv6 = 0;
8108         }
8109       else if (unformat (i, "%U %U",
8110                          unformat_ip6_address, &v6_src_address,
8111                          unformat_ip6_address, &v6_grp_address))
8112         {
8113           grp_address_length = 256;
8114           address_set = 1;
8115           is_ipv6 = 1;
8116         }
8117       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8118         {
8119           memset (&v4_src_address, 0, sizeof (v4_src_address));
8120           grp_address_length = 32;
8121           address_set = 1;
8122           is_ipv6 = 0;
8123         }
8124       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8125         {
8126           memset (&v6_src_address, 0, sizeof (v6_src_address));
8127           grp_address_length = 128;
8128           address_set = 1;
8129           is_ipv6 = 1;
8130         }
8131       else if (unformat (i, "/%d", &grp_address_length))
8132         ;
8133       else if (unformat (i, "local"))
8134         {
8135           is_local = 1;
8136         }
8137       else if (unformat (i, "del"))
8138         is_add = 0;
8139       else if (unformat (i, "add"))
8140         is_add = 1;
8141       else if (unformat (i, "vrf %d", &vrf_id))
8142         ;
8143       else if (unformat (i, "create-vrf"))
8144         create_vrf_if_needed = 1;
8145       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8146         ;
8147       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8148         ;
8149       else
8150         {
8151           clib_warning ("parse error '%U'", format_unformat_error, i);
8152           return -99;
8153         }
8154     }
8155
8156   if (address_set == 0)
8157     {
8158       errmsg ("missing addresses\n");
8159       return -99;
8160     }
8161
8162   /* Construct the API message */
8163   M (IP_MROUTE_ADD_DEL, mp);
8164
8165   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8166   mp->table_id = ntohl (vrf_id);
8167   mp->create_vrf_if_needed = create_vrf_if_needed;
8168
8169   mp->is_add = is_add;
8170   mp->is_ipv6 = is_ipv6;
8171   mp->is_local = is_local;
8172   mp->itf_flags = ntohl (iflags);
8173   mp->entry_flags = ntohl (eflags);
8174   mp->grp_address_length = grp_address_length;
8175   mp->grp_address_length = ntohs (mp->grp_address_length);
8176
8177   if (is_ipv6)
8178     {
8179       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8180       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8181     }
8182   else
8183     {
8184       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8185       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8186
8187     }
8188
8189   /* send it... */
8190   S (mp);
8191   /* Wait for a reply... */
8192   W (ret);
8193   return ret;
8194 }
8195
8196 static int
8197 api_mpls_table_add_del (vat_main_t * vam)
8198 {
8199   unformat_input_t *i = vam->input;
8200   vl_api_mpls_table_add_del_t *mp;
8201   u32 table_id = ~0;
8202   u8 is_add = 1;
8203   int ret = 0;
8204
8205   /* Parse args required to build the message */
8206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8207     {
8208       if (unformat (i, "table %d", &table_id))
8209         ;
8210       else if (unformat (i, "del"))
8211         is_add = 0;
8212       else if (unformat (i, "add"))
8213         is_add = 1;
8214       else
8215         {
8216           clib_warning ("parse error '%U'", format_unformat_error, i);
8217           return -99;
8218         }
8219     }
8220
8221   if (~0 == table_id)
8222     {
8223       errmsg ("missing table-ID");
8224       return -99;
8225     }
8226
8227   /* Construct the API message */
8228   M (MPLS_TABLE_ADD_DEL, mp);
8229
8230   mp->mt_table_id = ntohl (table_id);
8231   mp->mt_is_add = is_add;
8232
8233   /* send it... */
8234   S (mp);
8235
8236   /* Wait for a reply... */
8237   W (ret);
8238
8239   return ret;
8240 }
8241
8242 static int
8243 api_mpls_route_add_del (vat_main_t * vam)
8244 {
8245   unformat_input_t *i = vam->input;
8246   vl_api_mpls_route_add_del_t *mp;
8247   u32 sw_if_index = ~0, table_id = 0;
8248   u8 create_table_if_needed = 0;
8249   u8 is_add = 1;
8250   u32 next_hop_weight = 1;
8251   u8 is_multipath = 0;
8252   u32 next_hop_table_id = 0;
8253   u8 next_hop_set = 0;
8254   ip4_address_t v4_next_hop_address = {
8255     .as_u32 = 0,
8256   };
8257   ip6_address_t v6_next_hop_address = { {0} };
8258   int count = 1;
8259   int j;
8260   f64 before = 0;
8261   u32 classify_table_index = ~0;
8262   u8 is_classify = 0;
8263   u8 resolve_host = 0, resolve_attached = 0;
8264   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8265   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8266   mpls_label_t *next_hop_out_label_stack = NULL;
8267   mpls_label_t local_label = MPLS_LABEL_INVALID;
8268   u8 is_eos = 0;
8269   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8270
8271   /* Parse args required to build the message */
8272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8273     {
8274       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8275         ;
8276       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8277         ;
8278       else if (unformat (i, "%d", &local_label))
8279         ;
8280       else if (unformat (i, "eos"))
8281         is_eos = 1;
8282       else if (unformat (i, "non-eos"))
8283         is_eos = 0;
8284       else if (unformat (i, "via %U", unformat_ip4_address,
8285                          &v4_next_hop_address))
8286         {
8287           next_hop_set = 1;
8288           next_hop_proto = DPO_PROTO_IP4;
8289         }
8290       else if (unformat (i, "via %U", unformat_ip6_address,
8291                          &v6_next_hop_address))
8292         {
8293           next_hop_set = 1;
8294           next_hop_proto = DPO_PROTO_IP6;
8295         }
8296       else if (unformat (i, "weight %d", &next_hop_weight))
8297         ;
8298       else if (unformat (i, "create-table"))
8299         create_table_if_needed = 1;
8300       else if (unformat (i, "classify %d", &classify_table_index))
8301         {
8302           is_classify = 1;
8303         }
8304       else if (unformat (i, "del"))
8305         is_add = 0;
8306       else if (unformat (i, "add"))
8307         is_add = 1;
8308       else if (unformat (i, "resolve-via-host"))
8309         resolve_host = 1;
8310       else if (unformat (i, "resolve-via-attached"))
8311         resolve_attached = 1;
8312       else if (unformat (i, "multipath"))
8313         is_multipath = 1;
8314       else if (unformat (i, "count %d", &count))
8315         ;
8316       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8317         {
8318           next_hop_set = 1;
8319           next_hop_proto = DPO_PROTO_IP4;
8320         }
8321       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8322         {
8323           next_hop_set = 1;
8324           next_hop_proto = DPO_PROTO_IP6;
8325         }
8326       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8327         ;
8328       else if (unformat (i, "via-label %d", &next_hop_via_label))
8329         ;
8330       else if (unformat (i, "out-label %d", &next_hop_out_label))
8331         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8332       else
8333         {
8334           clib_warning ("parse error '%U'", format_unformat_error, i);
8335           return -99;
8336         }
8337     }
8338
8339   if (!next_hop_set && !is_classify)
8340     {
8341       errmsg ("next hop / classify not set");
8342       return -99;
8343     }
8344
8345   if (MPLS_LABEL_INVALID == local_label)
8346     {
8347       errmsg ("missing label");
8348       return -99;
8349     }
8350
8351   if (count > 1)
8352     {
8353       /* Turn on async mode */
8354       vam->async_mode = 1;
8355       vam->async_errors = 0;
8356       before = vat_time_now (vam);
8357     }
8358
8359   for (j = 0; j < count; j++)
8360     {
8361       /* Construct the API message */
8362       M2 (MPLS_ROUTE_ADD_DEL, mp,
8363           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8364
8365       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8366       mp->mr_table_id = ntohl (table_id);
8367       mp->mr_create_table_if_needed = create_table_if_needed;
8368
8369       mp->mr_is_add = is_add;
8370       mp->mr_next_hop_proto = next_hop_proto;
8371       mp->mr_is_classify = is_classify;
8372       mp->mr_is_multipath = is_multipath;
8373       mp->mr_is_resolve_host = resolve_host;
8374       mp->mr_is_resolve_attached = resolve_attached;
8375       mp->mr_next_hop_weight = next_hop_weight;
8376       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8377       mp->mr_classify_table_index = ntohl (classify_table_index);
8378       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8379       mp->mr_label = ntohl (local_label);
8380       mp->mr_eos = is_eos;
8381
8382       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8383       if (0 != mp->mr_next_hop_n_out_labels)
8384         {
8385           memcpy (mp->mr_next_hop_out_label_stack,
8386                   next_hop_out_label_stack,
8387                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8388           vec_free (next_hop_out_label_stack);
8389         }
8390
8391       if (next_hop_set)
8392         {
8393           if (DPO_PROTO_IP4 == next_hop_proto)
8394             {
8395               clib_memcpy (mp->mr_next_hop,
8396                            &v4_next_hop_address,
8397                            sizeof (v4_next_hop_address));
8398             }
8399           else if (DPO_PROTO_IP6 == next_hop_proto)
8400
8401             {
8402               clib_memcpy (mp->mr_next_hop,
8403                            &v6_next_hop_address,
8404                            sizeof (v6_next_hop_address));
8405             }
8406         }
8407       local_label++;
8408
8409       /* send it... */
8410       S (mp);
8411       /* If we receive SIGTERM, stop now... */
8412       if (vam->do_exit)
8413         break;
8414     }
8415
8416   /* When testing multiple add/del ops, use a control-ping to sync */
8417   if (count > 1)
8418     {
8419       vl_api_control_ping_t *mp_ping;
8420       f64 after;
8421       f64 timeout;
8422
8423       /* Shut off async mode */
8424       vam->async_mode = 0;
8425
8426       MPING (CONTROL_PING, mp_ping);
8427       S (mp_ping);
8428
8429       timeout = vat_time_now (vam) + 1.0;
8430       while (vat_time_now (vam) < timeout)
8431         if (vam->result_ready == 1)
8432           goto out;
8433       vam->retval = -99;
8434
8435     out:
8436       if (vam->retval == -99)
8437         errmsg ("timeout");
8438
8439       if (vam->async_errors > 0)
8440         {
8441           errmsg ("%d asynchronous errors", vam->async_errors);
8442           vam->retval = -98;
8443         }
8444       vam->async_errors = 0;
8445       after = vat_time_now (vam);
8446
8447       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8448       if (j > 0)
8449         count = j;
8450
8451       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8452              count, after - before, count / (after - before));
8453     }
8454   else
8455     {
8456       int ret;
8457
8458       /* Wait for a reply... */
8459       W (ret);
8460       return ret;
8461     }
8462
8463   /* Return the good/bad news */
8464   return (vam->retval);
8465 }
8466
8467 static int
8468 api_mpls_ip_bind_unbind (vat_main_t * vam)
8469 {
8470   unformat_input_t *i = vam->input;
8471   vl_api_mpls_ip_bind_unbind_t *mp;
8472   u32 ip_table_id = 0;
8473   u8 create_table_if_needed = 0;
8474   u8 is_bind = 1;
8475   u8 is_ip4 = 1;
8476   ip4_address_t v4_address;
8477   ip6_address_t v6_address;
8478   u32 address_length;
8479   u8 address_set = 0;
8480   mpls_label_t local_label = MPLS_LABEL_INVALID;
8481   int ret;
8482
8483   /* Parse args required to build the message */
8484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8485     {
8486       if (unformat (i, "%U/%d", unformat_ip4_address,
8487                     &v4_address, &address_length))
8488         {
8489           is_ip4 = 1;
8490           address_set = 1;
8491         }
8492       else if (unformat (i, "%U/%d", unformat_ip6_address,
8493                          &v6_address, &address_length))
8494         {
8495           is_ip4 = 0;
8496           address_set = 1;
8497         }
8498       else if (unformat (i, "%d", &local_label))
8499         ;
8500       else if (unformat (i, "create-table"))
8501         create_table_if_needed = 1;
8502       else if (unformat (i, "table-id %d", &ip_table_id))
8503         ;
8504       else if (unformat (i, "unbind"))
8505         is_bind = 0;
8506       else if (unformat (i, "bind"))
8507         is_bind = 1;
8508       else
8509         {
8510           clib_warning ("parse error '%U'", format_unformat_error, i);
8511           return -99;
8512         }
8513     }
8514
8515   if (!address_set)
8516     {
8517       errmsg ("IP addres not set");
8518       return -99;
8519     }
8520
8521   if (MPLS_LABEL_INVALID == local_label)
8522     {
8523       errmsg ("missing label");
8524       return -99;
8525     }
8526
8527   /* Construct the API message */
8528   M (MPLS_IP_BIND_UNBIND, mp);
8529
8530   mp->mb_create_table_if_needed = create_table_if_needed;
8531   mp->mb_is_bind = is_bind;
8532   mp->mb_is_ip4 = is_ip4;
8533   mp->mb_ip_table_id = ntohl (ip_table_id);
8534   mp->mb_mpls_table_id = 0;
8535   mp->mb_label = ntohl (local_label);
8536   mp->mb_address_length = address_length;
8537
8538   if (is_ip4)
8539     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8540   else
8541     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8542
8543   /* send it... */
8544   S (mp);
8545
8546   /* Wait for a reply... */
8547   W (ret);
8548   return ret;
8549 }
8550
8551 static int
8552 api_bier_table_add_del (vat_main_t * vam)
8553 {
8554   unformat_input_t *i = vam->input;
8555   vl_api_bier_table_add_del_t *mp;
8556   u8 is_add = 1;
8557   u32 set = 0, sub_domain = 0, hdr_len = 3;
8558   mpls_label_t local_label = MPLS_LABEL_INVALID;
8559   int ret;
8560
8561   /* Parse args required to build the message */
8562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (i, "sub-domain %d", &sub_domain))
8565         ;
8566       else if (unformat (i, "set %d", &set))
8567         ;
8568       else if (unformat (i, "label %d", &local_label))
8569         ;
8570       else if (unformat (i, "hdr-len %d", &hdr_len))
8571         ;
8572       else if (unformat (i, "add"))
8573         is_add = 1;
8574       else if (unformat (i, "del"))
8575         is_add = 0;
8576       else
8577         {
8578           clib_warning ("parse error '%U'", format_unformat_error, i);
8579           return -99;
8580         }
8581     }
8582
8583   if (MPLS_LABEL_INVALID == local_label)
8584     {
8585       errmsg ("missing label\n");
8586       return -99;
8587     }
8588
8589   /* Construct the API message */
8590   M (BIER_TABLE_ADD_DEL, mp);
8591
8592   mp->bt_is_add = is_add;
8593   mp->bt_label = ntohl (local_label);
8594   mp->bt_tbl_id.bt_set = set;
8595   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8596   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8597
8598   /* send it... */
8599   S (mp);
8600
8601   /* Wait for a reply... */
8602   W (ret);
8603
8604   return (ret);
8605 }
8606
8607 static int
8608 api_bier_route_add_del (vat_main_t * vam)
8609 {
8610   unformat_input_t *i = vam->input;
8611   vl_api_bier_route_add_del_t *mp;
8612   u8 is_add = 1;
8613   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8614   ip4_address_t v4_next_hop_address;
8615   ip6_address_t v6_next_hop_address;
8616   u8 next_hop_set = 0;
8617   u8 next_hop_proto_is_ip4 = 1;
8618   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8619   int ret;
8620
8621   /* Parse args required to build the message */
8622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8623     {
8624       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8625         {
8626           next_hop_proto_is_ip4 = 1;
8627           next_hop_set = 1;
8628         }
8629       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8630         {
8631           next_hop_proto_is_ip4 = 0;
8632           next_hop_set = 1;
8633         }
8634       if (unformat (i, "sub-domain %d", &sub_domain))
8635         ;
8636       else if (unformat (i, "set %d", &set))
8637         ;
8638       else if (unformat (i, "hdr-len %d", &hdr_len))
8639         ;
8640       else if (unformat (i, "bp %d", &bp))
8641         ;
8642       else if (unformat (i, "add"))
8643         is_add = 1;
8644       else if (unformat (i, "del"))
8645         is_add = 0;
8646       else if (unformat (i, "out-label %d", &next_hop_out_label))
8647         ;
8648       else
8649         {
8650           clib_warning ("parse error '%U'", format_unformat_error, i);
8651           return -99;
8652         }
8653     }
8654
8655   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8656     {
8657       errmsg ("next hop / label set\n");
8658       return -99;
8659     }
8660   if (0 == bp)
8661     {
8662       errmsg ("bit=position not set\n");
8663       return -99;
8664     }
8665
8666   /* Construct the API message */
8667   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8668
8669   mp->br_is_add = is_add;
8670   mp->br_tbl_id.bt_set = set;
8671   mp->br_tbl_id.bt_sub_domain = sub_domain;
8672   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8673   mp->br_bp = ntohs (bp);
8674   mp->br_n_paths = 1;
8675   mp->br_paths[0].n_labels = 1;
8676   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8677   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8678
8679   if (next_hop_proto_is_ip4)
8680     {
8681       clib_memcpy (mp->br_paths[0].next_hop,
8682                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8683     }
8684   else
8685     {
8686       clib_memcpy (mp->br_paths[0].next_hop,
8687                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8688     }
8689
8690   /* send it... */
8691   S (mp);
8692
8693   /* Wait for a reply... */
8694   W (ret);
8695
8696   return (ret);
8697 }
8698
8699 static int
8700 api_proxy_arp_add_del (vat_main_t * vam)
8701 {
8702   unformat_input_t *i = vam->input;
8703   vl_api_proxy_arp_add_del_t *mp;
8704   u32 vrf_id = 0;
8705   u8 is_add = 1;
8706   ip4_address_t lo, hi;
8707   u8 range_set = 0;
8708   int ret;
8709
8710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8711     {
8712       if (unformat (i, "vrf %d", &vrf_id))
8713         ;
8714       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8715                          unformat_ip4_address, &hi))
8716         range_set = 1;
8717       else if (unformat (i, "del"))
8718         is_add = 0;
8719       else
8720         {
8721           clib_warning ("parse error '%U'", format_unformat_error, i);
8722           return -99;
8723         }
8724     }
8725
8726   if (range_set == 0)
8727     {
8728       errmsg ("address range not set");
8729       return -99;
8730     }
8731
8732   M (PROXY_ARP_ADD_DEL, mp);
8733
8734   mp->vrf_id = ntohl (vrf_id);
8735   mp->is_add = is_add;
8736   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8737   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8738
8739   S (mp);
8740   W (ret);
8741   return ret;
8742 }
8743
8744 static int
8745 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8746 {
8747   unformat_input_t *i = vam->input;
8748   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8749   u32 sw_if_index;
8750   u8 enable = 1;
8751   u8 sw_if_index_set = 0;
8752   int ret;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8757         sw_if_index_set = 1;
8758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8759         sw_if_index_set = 1;
8760       else if (unformat (i, "enable"))
8761         enable = 1;
8762       else if (unformat (i, "disable"))
8763         enable = 0;
8764       else
8765         {
8766           clib_warning ("parse error '%U'", format_unformat_error, i);
8767           return -99;
8768         }
8769     }
8770
8771   if (sw_if_index_set == 0)
8772     {
8773       errmsg ("missing interface name or sw_if_index");
8774       return -99;
8775     }
8776
8777   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8778
8779   mp->sw_if_index = ntohl (sw_if_index);
8780   mp->enable_disable = enable;
8781
8782   S (mp);
8783   W (ret);
8784   return ret;
8785 }
8786
8787 static int
8788 api_mpls_tunnel_add_del (vat_main_t * vam)
8789 {
8790   unformat_input_t *i = vam->input;
8791   vl_api_mpls_tunnel_add_del_t *mp;
8792
8793   u8 is_add = 1;
8794   u8 l2_only = 0;
8795   u32 sw_if_index = ~0;
8796   u32 next_hop_sw_if_index = ~0;
8797   u32 next_hop_proto_is_ip4 = 1;
8798
8799   u32 next_hop_table_id = 0;
8800   ip4_address_t v4_next_hop_address = {
8801     .as_u32 = 0,
8802   };
8803   ip6_address_t v6_next_hop_address = { {0} };
8804   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8805   int ret;
8806
8807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808     {
8809       if (unformat (i, "add"))
8810         is_add = 1;
8811       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8812         is_add = 0;
8813       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8814         ;
8815       else if (unformat (i, "via %U",
8816                          unformat_ip4_address, &v4_next_hop_address))
8817         {
8818           next_hop_proto_is_ip4 = 1;
8819         }
8820       else if (unformat (i, "via %U",
8821                          unformat_ip6_address, &v6_next_hop_address))
8822         {
8823           next_hop_proto_is_ip4 = 0;
8824         }
8825       else if (unformat (i, "l2-only"))
8826         l2_only = 1;
8827       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8828         ;
8829       else if (unformat (i, "out-label %d", &next_hop_out_label))
8830         vec_add1 (labels, ntohl (next_hop_out_label));
8831       else
8832         {
8833           clib_warning ("parse error '%U'", format_unformat_error, i);
8834           return -99;
8835         }
8836     }
8837
8838   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8839
8840   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8841   mp->mt_sw_if_index = ntohl (sw_if_index);
8842   mp->mt_is_add = is_add;
8843   mp->mt_l2_only = l2_only;
8844   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8845   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8846
8847   mp->mt_next_hop_n_out_labels = vec_len (labels);
8848
8849   if (0 != mp->mt_next_hop_n_out_labels)
8850     {
8851       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8852                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8853       vec_free (labels);
8854     }
8855
8856   if (next_hop_proto_is_ip4)
8857     {
8858       clib_memcpy (mp->mt_next_hop,
8859                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8860     }
8861   else
8862     {
8863       clib_memcpy (mp->mt_next_hop,
8864                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8865     }
8866
8867   S (mp);
8868   W (ret);
8869   return ret;
8870 }
8871
8872 static int
8873 api_sw_interface_set_unnumbered (vat_main_t * vam)
8874 {
8875   unformat_input_t *i = vam->input;
8876   vl_api_sw_interface_set_unnumbered_t *mp;
8877   u32 sw_if_index;
8878   u32 unnum_sw_index = ~0;
8879   u8 is_add = 1;
8880   u8 sw_if_index_set = 0;
8881   int ret;
8882
8883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8884     {
8885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8886         sw_if_index_set = 1;
8887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8888         sw_if_index_set = 1;
8889       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8890         ;
8891       else if (unformat (i, "del"))
8892         is_add = 0;
8893       else
8894         {
8895           clib_warning ("parse error '%U'", format_unformat_error, i);
8896           return -99;
8897         }
8898     }
8899
8900   if (sw_if_index_set == 0)
8901     {
8902       errmsg ("missing interface name or sw_if_index");
8903       return -99;
8904     }
8905
8906   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8907
8908   mp->sw_if_index = ntohl (sw_if_index);
8909   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8910   mp->is_add = is_add;
8911
8912   S (mp);
8913   W (ret);
8914   return ret;
8915 }
8916
8917 static int
8918 api_ip_neighbor_add_del (vat_main_t * vam)
8919 {
8920   unformat_input_t *i = vam->input;
8921   vl_api_ip_neighbor_add_del_t *mp;
8922   u32 sw_if_index;
8923   u8 sw_if_index_set = 0;
8924   u8 is_add = 1;
8925   u8 is_static = 0;
8926   u8 is_no_fib_entry = 0;
8927   u8 mac_address[6];
8928   u8 mac_set = 0;
8929   u8 v4_address_set = 0;
8930   u8 v6_address_set = 0;
8931   ip4_address_t v4address;
8932   ip6_address_t v6address;
8933   int ret;
8934
8935   memset (mac_address, 0, sizeof (mac_address));
8936
8937   /* Parse args required to build the message */
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8941         {
8942           mac_set = 1;
8943         }
8944       else if (unformat (i, "del"))
8945         is_add = 0;
8946       else
8947         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8948         sw_if_index_set = 1;
8949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         sw_if_index_set = 1;
8951       else if (unformat (i, "is_static"))
8952         is_static = 1;
8953       else if (unformat (i, "no-fib-entry"))
8954         is_no_fib_entry = 1;
8955       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8956         v4_address_set = 1;
8957       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8958         v6_address_set = 1;
8959       else
8960         {
8961           clib_warning ("parse error '%U'", format_unformat_error, i);
8962           return -99;
8963         }
8964     }
8965
8966   if (sw_if_index_set == 0)
8967     {
8968       errmsg ("missing interface name or sw_if_index");
8969       return -99;
8970     }
8971   if (v4_address_set && v6_address_set)
8972     {
8973       errmsg ("both v4 and v6 addresses set");
8974       return -99;
8975     }
8976   if (!v4_address_set && !v6_address_set)
8977     {
8978       errmsg ("no address set");
8979       return -99;
8980     }
8981
8982   /* Construct the API message */
8983   M (IP_NEIGHBOR_ADD_DEL, mp);
8984
8985   mp->sw_if_index = ntohl (sw_if_index);
8986   mp->is_add = is_add;
8987   mp->is_static = is_static;
8988   mp->is_no_adj_fib = is_no_fib_entry;
8989   if (mac_set)
8990     clib_memcpy (mp->mac_address, mac_address, 6);
8991   if (v6_address_set)
8992     {
8993       mp->is_ipv6 = 1;
8994       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8995     }
8996   else
8997     {
8998       /* mp->is_ipv6 = 0; via memset in M macro above */
8999       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9000     }
9001
9002   /* send it... */
9003   S (mp);
9004
9005   /* Wait for a reply, return good/bad news  */
9006   W (ret);
9007   return ret;
9008 }
9009
9010 static int
9011 api_create_vlan_subif (vat_main_t * vam)
9012 {
9013   unformat_input_t *i = vam->input;
9014   vl_api_create_vlan_subif_t *mp;
9015   u32 sw_if_index;
9016   u8 sw_if_index_set = 0;
9017   u32 vlan_id;
9018   u8 vlan_id_set = 0;
9019   int ret;
9020
9021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9022     {
9023       if (unformat (i, "sw_if_index %d", &sw_if_index))
9024         sw_if_index_set = 1;
9025       else
9026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9027         sw_if_index_set = 1;
9028       else if (unformat (i, "vlan %d", &vlan_id))
9029         vlan_id_set = 1;
9030       else
9031         {
9032           clib_warning ("parse error '%U'", format_unformat_error, i);
9033           return -99;
9034         }
9035     }
9036
9037   if (sw_if_index_set == 0)
9038     {
9039       errmsg ("missing interface name or sw_if_index");
9040       return -99;
9041     }
9042
9043   if (vlan_id_set == 0)
9044     {
9045       errmsg ("missing vlan_id");
9046       return -99;
9047     }
9048   M (CREATE_VLAN_SUBIF, mp);
9049
9050   mp->sw_if_index = ntohl (sw_if_index);
9051   mp->vlan_id = ntohl (vlan_id);
9052
9053   S (mp);
9054   W (ret);
9055   return ret;
9056 }
9057
9058 #define foreach_create_subif_bit                \
9059 _(no_tags)                                      \
9060 _(one_tag)                                      \
9061 _(two_tags)                                     \
9062 _(dot1ad)                                       \
9063 _(exact_match)                                  \
9064 _(default_sub)                                  \
9065 _(outer_vlan_id_any)                            \
9066 _(inner_vlan_id_any)
9067
9068 static int
9069 api_create_subif (vat_main_t * vam)
9070 {
9071   unformat_input_t *i = vam->input;
9072   vl_api_create_subif_t *mp;
9073   u32 sw_if_index;
9074   u8 sw_if_index_set = 0;
9075   u32 sub_id;
9076   u8 sub_id_set = 0;
9077   u32 no_tags = 0;
9078   u32 one_tag = 0;
9079   u32 two_tags = 0;
9080   u32 dot1ad = 0;
9081   u32 exact_match = 0;
9082   u32 default_sub = 0;
9083   u32 outer_vlan_id_any = 0;
9084   u32 inner_vlan_id_any = 0;
9085   u32 tmp;
9086   u16 outer_vlan_id = 0;
9087   u16 inner_vlan_id = 0;
9088   int ret;
9089
9090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (i, "sw_if_index %d", &sw_if_index))
9093         sw_if_index_set = 1;
9094       else
9095         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "sub_id %d", &sub_id))
9098         sub_id_set = 1;
9099       else if (unformat (i, "outer_vlan_id %d", &tmp))
9100         outer_vlan_id = tmp;
9101       else if (unformat (i, "inner_vlan_id %d", &tmp))
9102         inner_vlan_id = tmp;
9103
9104 #define _(a) else if (unformat (i, #a)) a = 1 ;
9105       foreach_create_subif_bit
9106 #undef _
9107         else
9108         {
9109           clib_warning ("parse error '%U'", format_unformat_error, i);
9110           return -99;
9111         }
9112     }
9113
9114   if (sw_if_index_set == 0)
9115     {
9116       errmsg ("missing interface name or sw_if_index");
9117       return -99;
9118     }
9119
9120   if (sub_id_set == 0)
9121     {
9122       errmsg ("missing sub_id");
9123       return -99;
9124     }
9125   M (CREATE_SUBIF, mp);
9126
9127   mp->sw_if_index = ntohl (sw_if_index);
9128   mp->sub_id = ntohl (sub_id);
9129
9130 #define _(a) mp->a = a;
9131   foreach_create_subif_bit;
9132 #undef _
9133
9134   mp->outer_vlan_id = ntohs (outer_vlan_id);
9135   mp->inner_vlan_id = ntohs (inner_vlan_id);
9136
9137   S (mp);
9138   W (ret);
9139   return ret;
9140 }
9141
9142 static int
9143 api_oam_add_del (vat_main_t * vam)
9144 {
9145   unformat_input_t *i = vam->input;
9146   vl_api_oam_add_del_t *mp;
9147   u32 vrf_id = 0;
9148   u8 is_add = 1;
9149   ip4_address_t src, dst;
9150   u8 src_set = 0;
9151   u8 dst_set = 0;
9152   int ret;
9153
9154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9155     {
9156       if (unformat (i, "vrf %d", &vrf_id))
9157         ;
9158       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9159         src_set = 1;
9160       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9161         dst_set = 1;
9162       else if (unformat (i, "del"))
9163         is_add = 0;
9164       else
9165         {
9166           clib_warning ("parse error '%U'", format_unformat_error, i);
9167           return -99;
9168         }
9169     }
9170
9171   if (src_set == 0)
9172     {
9173       errmsg ("missing src addr");
9174       return -99;
9175     }
9176
9177   if (dst_set == 0)
9178     {
9179       errmsg ("missing dst addr");
9180       return -99;
9181     }
9182
9183   M (OAM_ADD_DEL, mp);
9184
9185   mp->vrf_id = ntohl (vrf_id);
9186   mp->is_add = is_add;
9187   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9188   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9189
9190   S (mp);
9191   W (ret);
9192   return ret;
9193 }
9194
9195 static int
9196 api_reset_fib (vat_main_t * vam)
9197 {
9198   unformat_input_t *i = vam->input;
9199   vl_api_reset_fib_t *mp;
9200   u32 vrf_id = 0;
9201   u8 is_ipv6 = 0;
9202   u8 vrf_id_set = 0;
9203
9204   int ret;
9205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (i, "vrf %d", &vrf_id))
9208         vrf_id_set = 1;
9209       else if (unformat (i, "ipv6"))
9210         is_ipv6 = 1;
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   if (vrf_id_set == 0)
9219     {
9220       errmsg ("missing vrf id");
9221       return -99;
9222     }
9223
9224   M (RESET_FIB, mp);
9225
9226   mp->vrf_id = ntohl (vrf_id);
9227   mp->is_ipv6 = is_ipv6;
9228
9229   S (mp);
9230   W (ret);
9231   return ret;
9232 }
9233
9234 static int
9235 api_dhcp_proxy_config (vat_main_t * vam)
9236 {
9237   unformat_input_t *i = vam->input;
9238   vl_api_dhcp_proxy_config_t *mp;
9239   u32 rx_vrf_id = 0;
9240   u32 server_vrf_id = 0;
9241   u8 is_add = 1;
9242   u8 v4_address_set = 0;
9243   u8 v6_address_set = 0;
9244   ip4_address_t v4address;
9245   ip6_address_t v6address;
9246   u8 v4_src_address_set = 0;
9247   u8 v6_src_address_set = 0;
9248   ip4_address_t v4srcaddress;
9249   ip6_address_t v6srcaddress;
9250   int ret;
9251
9252   /* Parse args required to build the message */
9253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9254     {
9255       if (unformat (i, "del"))
9256         is_add = 0;
9257       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9258         ;
9259       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9260         ;
9261       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9262         v4_address_set = 1;
9263       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9264         v6_address_set = 1;
9265       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9266         v4_src_address_set = 1;
9267       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9268         v6_src_address_set = 1;
9269       else
9270         break;
9271     }
9272
9273   if (v4_address_set && v6_address_set)
9274     {
9275       errmsg ("both v4 and v6 server addresses set");
9276       return -99;
9277     }
9278   if (!v4_address_set && !v6_address_set)
9279     {
9280       errmsg ("no server addresses set");
9281       return -99;
9282     }
9283
9284   if (v4_src_address_set && v6_src_address_set)
9285     {
9286       errmsg ("both v4 and v6  src addresses set");
9287       return -99;
9288     }
9289   if (!v4_src_address_set && !v6_src_address_set)
9290     {
9291       errmsg ("no src addresses set");
9292       return -99;
9293     }
9294
9295   if (!(v4_src_address_set && v4_address_set) &&
9296       !(v6_src_address_set && v6_address_set))
9297     {
9298       errmsg ("no matching server and src addresses set");
9299       return -99;
9300     }
9301
9302   /* Construct the API message */
9303   M (DHCP_PROXY_CONFIG, mp);
9304
9305   mp->is_add = is_add;
9306   mp->rx_vrf_id = ntohl (rx_vrf_id);
9307   mp->server_vrf_id = ntohl (server_vrf_id);
9308   if (v6_address_set)
9309     {
9310       mp->is_ipv6 = 1;
9311       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9312       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9313     }
9314   else
9315     {
9316       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9317       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9318     }
9319
9320   /* send it... */
9321   S (mp);
9322
9323   /* Wait for a reply, return good/bad news  */
9324   W (ret);
9325   return ret;
9326 }
9327
9328 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9329 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9330
9331 static void
9332 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9333 {
9334   vat_main_t *vam = &vat_main;
9335   u32 i, count = mp->count;
9336   vl_api_dhcp_server_t *s;
9337
9338   if (mp->is_ipv6)
9339     print (vam->ofp,
9340            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9341            ntohl (mp->rx_vrf_id),
9342            format_ip6_address, mp->dhcp_src_address,
9343            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9344   else
9345     print (vam->ofp,
9346            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9347            ntohl (mp->rx_vrf_id),
9348            format_ip4_address, mp->dhcp_src_address,
9349            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9350
9351   for (i = 0; i < count; i++)
9352     {
9353       s = &mp->servers[i];
9354
9355       if (mp->is_ipv6)
9356         print (vam->ofp,
9357                " Server Table-ID %d, Server Address %U",
9358                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9359       else
9360         print (vam->ofp,
9361                " Server Table-ID %d, Server Address %U",
9362                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9363     }
9364 }
9365
9366 static void vl_api_dhcp_proxy_details_t_handler_json
9367   (vl_api_dhcp_proxy_details_t * mp)
9368 {
9369   vat_main_t *vam = &vat_main;
9370   vat_json_node_t *node = NULL;
9371   u32 i, count = mp->count;
9372   struct in_addr ip4;
9373   struct in6_addr ip6;
9374   vl_api_dhcp_server_t *s;
9375
9376   if (VAT_JSON_ARRAY != vam->json_tree.type)
9377     {
9378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9379       vat_json_init_array (&vam->json_tree);
9380     }
9381   node = vat_json_array_add (&vam->json_tree);
9382
9383   vat_json_init_object (node);
9384   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9385   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9386   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9387
9388   if (mp->is_ipv6)
9389     {
9390       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9391       vat_json_object_add_ip6 (node, "src_address", ip6);
9392     }
9393   else
9394     {
9395       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9396       vat_json_object_add_ip4 (node, "src_address", ip4);
9397     }
9398
9399   for (i = 0; i < count; i++)
9400     {
9401       s = &mp->servers[i];
9402
9403       vat_json_object_add_uint (node, "server-table-id",
9404                                 ntohl (s->server_vrf_id));
9405
9406       if (mp->is_ipv6)
9407         {
9408           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9409           vat_json_object_add_ip4 (node, "src_address", ip4);
9410         }
9411       else
9412         {
9413           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9414           vat_json_object_add_ip6 (node, "server_address", ip6);
9415         }
9416     }
9417 }
9418
9419 static int
9420 api_dhcp_proxy_dump (vat_main_t * vam)
9421 {
9422   unformat_input_t *i = vam->input;
9423   vl_api_control_ping_t *mp_ping;
9424   vl_api_dhcp_proxy_dump_t *mp;
9425   u8 is_ipv6 = 0;
9426   int ret;
9427
9428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9429     {
9430       if (unformat (i, "ipv6"))
9431         is_ipv6 = 1;
9432       else
9433         {
9434           clib_warning ("parse error '%U'", format_unformat_error, i);
9435           return -99;
9436         }
9437     }
9438
9439   M (DHCP_PROXY_DUMP, mp);
9440
9441   mp->is_ip6 = is_ipv6;
9442   S (mp);
9443
9444   /* Use a control ping for synchronization */
9445   MPING (CONTROL_PING, mp_ping);
9446   S (mp_ping);
9447
9448   W (ret);
9449   return ret;
9450 }
9451
9452 static int
9453 api_dhcp_proxy_set_vss (vat_main_t * vam)
9454 {
9455   unformat_input_t *i = vam->input;
9456   vl_api_dhcp_proxy_set_vss_t *mp;
9457   u8 is_ipv6 = 0;
9458   u8 is_add = 1;
9459   u32 tbl_id;
9460   u8 tbl_id_set = 0;
9461   u32 oui;
9462   u8 oui_set = 0;
9463   u32 fib_id;
9464   u8 fib_id_set = 0;
9465   int ret;
9466
9467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9468     {
9469       if (unformat (i, "tbl_id %d", &tbl_id))
9470         tbl_id_set = 1;
9471       if (unformat (i, "fib_id %d", &fib_id))
9472         fib_id_set = 1;
9473       if (unformat (i, "oui %d", &oui))
9474         oui_set = 1;
9475       else if (unformat (i, "ipv6"))
9476         is_ipv6 = 1;
9477       else if (unformat (i, "del"))
9478         is_add = 0;
9479       else
9480         {
9481           clib_warning ("parse error '%U'", format_unformat_error, i);
9482           return -99;
9483         }
9484     }
9485
9486   if (tbl_id_set == 0)
9487     {
9488       errmsg ("missing tbl id");
9489       return -99;
9490     }
9491
9492   if (fib_id_set == 0)
9493     {
9494       errmsg ("missing fib id");
9495       return -99;
9496     }
9497   if (oui_set == 0)
9498     {
9499       errmsg ("missing oui");
9500       return -99;
9501     }
9502
9503   M (DHCP_PROXY_SET_VSS, mp);
9504   mp->tbl_id = ntohl (tbl_id);
9505   mp->fib_id = ntohl (fib_id);
9506   mp->oui = ntohl (oui);
9507   mp->is_ipv6 = is_ipv6;
9508   mp->is_add = is_add;
9509
9510   S (mp);
9511   W (ret);
9512   return ret;
9513 }
9514
9515 static int
9516 api_dhcp_client_config (vat_main_t * vam)
9517 {
9518   unformat_input_t *i = vam->input;
9519   vl_api_dhcp_client_config_t *mp;
9520   u32 sw_if_index;
9521   u8 sw_if_index_set = 0;
9522   u8 is_add = 1;
9523   u8 *hostname = 0;
9524   u8 disable_event = 0;
9525   int ret;
9526
9527   /* Parse args required to build the message */
9528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9529     {
9530       if (unformat (i, "del"))
9531         is_add = 0;
9532       else
9533         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9534         sw_if_index_set = 1;
9535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9536         sw_if_index_set = 1;
9537       else if (unformat (i, "hostname %s", &hostname))
9538         ;
9539       else if (unformat (i, "disable_event"))
9540         disable_event = 1;
9541       else
9542         break;
9543     }
9544
9545   if (sw_if_index_set == 0)
9546     {
9547       errmsg ("missing interface name or sw_if_index");
9548       return -99;
9549     }
9550
9551   if (vec_len (hostname) > 63)
9552     {
9553       errmsg ("hostname too long");
9554     }
9555   vec_add1 (hostname, 0);
9556
9557   /* Construct the API message */
9558   M (DHCP_CLIENT_CONFIG, mp);
9559
9560   mp->sw_if_index = htonl (sw_if_index);
9561   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9562   vec_free (hostname);
9563   mp->is_add = is_add;
9564   mp->want_dhcp_event = disable_event ? 0 : 1;
9565   mp->pid = htonl (getpid ());
9566
9567   /* send it... */
9568   S (mp);
9569
9570   /* Wait for a reply, return good/bad news  */
9571   W (ret);
9572   return ret;
9573 }
9574
9575 static int
9576 api_set_ip_flow_hash (vat_main_t * vam)
9577 {
9578   unformat_input_t *i = vam->input;
9579   vl_api_set_ip_flow_hash_t *mp;
9580   u32 vrf_id = 0;
9581   u8 is_ipv6 = 0;
9582   u8 vrf_id_set = 0;
9583   u8 src = 0;
9584   u8 dst = 0;
9585   u8 sport = 0;
9586   u8 dport = 0;
9587   u8 proto = 0;
9588   u8 reverse = 0;
9589   int ret;
9590
9591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (i, "vrf %d", &vrf_id))
9594         vrf_id_set = 1;
9595       else if (unformat (i, "ipv6"))
9596         is_ipv6 = 1;
9597       else if (unformat (i, "src"))
9598         src = 1;
9599       else if (unformat (i, "dst"))
9600         dst = 1;
9601       else if (unformat (i, "sport"))
9602         sport = 1;
9603       else if (unformat (i, "dport"))
9604         dport = 1;
9605       else if (unformat (i, "proto"))
9606         proto = 1;
9607       else if (unformat (i, "reverse"))
9608         reverse = 1;
9609
9610       else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (vrf_id_set == 0)
9618     {
9619       errmsg ("missing vrf id");
9620       return -99;
9621     }
9622
9623   M (SET_IP_FLOW_HASH, mp);
9624   mp->src = src;
9625   mp->dst = dst;
9626   mp->sport = sport;
9627   mp->dport = dport;
9628   mp->proto = proto;
9629   mp->reverse = reverse;
9630   mp->vrf_id = ntohl (vrf_id);
9631   mp->is_ipv6 = is_ipv6;
9632
9633   S (mp);
9634   W (ret);
9635   return ret;
9636 }
9637
9638 static int
9639 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9640 {
9641   unformat_input_t *i = vam->input;
9642   vl_api_sw_interface_ip6_enable_disable_t *mp;
9643   u32 sw_if_index;
9644   u8 sw_if_index_set = 0;
9645   u8 enable = 0;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9651         sw_if_index_set = 1;
9652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9653         sw_if_index_set = 1;
9654       else if (unformat (i, "enable"))
9655         enable = 1;
9656       else if (unformat (i, "disable"))
9657         enable = 0;
9658       else
9659         {
9660           clib_warning ("parse error '%U'", format_unformat_error, i);
9661           return -99;
9662         }
9663     }
9664
9665   if (sw_if_index_set == 0)
9666     {
9667       errmsg ("missing interface name or sw_if_index");
9668       return -99;
9669     }
9670
9671   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9672
9673   mp->sw_if_index = ntohl (sw_if_index);
9674   mp->enable = enable;
9675
9676   S (mp);
9677   W (ret);
9678   return ret;
9679 }
9680
9681 static int
9682 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9683 {
9684   unformat_input_t *i = vam->input;
9685   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9686   u32 sw_if_index;
9687   u8 sw_if_index_set = 0;
9688   u8 v6_address_set = 0;
9689   ip6_address_t v6address;
9690   int ret;
9691
9692   /* Parse args required to build the message */
9693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9694     {
9695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9696         sw_if_index_set = 1;
9697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9698         sw_if_index_set = 1;
9699       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9700         v6_address_set = 1;
9701       else
9702         break;
9703     }
9704
9705   if (sw_if_index_set == 0)
9706     {
9707       errmsg ("missing interface name or sw_if_index");
9708       return -99;
9709     }
9710   if (!v6_address_set)
9711     {
9712       errmsg ("no address set");
9713       return -99;
9714     }
9715
9716   /* Construct the API message */
9717   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9718
9719   mp->sw_if_index = ntohl (sw_if_index);
9720   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9721
9722   /* send it... */
9723   S (mp);
9724
9725   /* Wait for a reply, return good/bad news  */
9726   W (ret);
9727   return ret;
9728 }
9729
9730 static int
9731 api_ip6nd_proxy_add_del (vat_main_t * vam)
9732 {
9733   unformat_input_t *i = vam->input;
9734   vl_api_ip6nd_proxy_add_del_t *mp;
9735   u32 sw_if_index = ~0;
9736   u8 v6_address_set = 0;
9737   ip6_address_t v6address;
9738   u8 is_del = 0;
9739   int ret;
9740
9741   /* Parse args required to build the message */
9742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9743     {
9744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9745         ;
9746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9747         ;
9748       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9749         v6_address_set = 1;
9750       if (unformat (i, "del"))
9751         is_del = 1;
9752       else
9753         {
9754           clib_warning ("parse error '%U'", format_unformat_error, i);
9755           return -99;
9756         }
9757     }
9758
9759   if (sw_if_index == ~0)
9760     {
9761       errmsg ("missing interface name or sw_if_index");
9762       return -99;
9763     }
9764   if (!v6_address_set)
9765     {
9766       errmsg ("no address set");
9767       return -99;
9768     }
9769
9770   /* Construct the API message */
9771   M (IP6ND_PROXY_ADD_DEL, mp);
9772
9773   mp->is_del = is_del;
9774   mp->sw_if_index = ntohl (sw_if_index);
9775   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9776
9777   /* send it... */
9778   S (mp);
9779
9780   /* Wait for a reply, return good/bad news  */
9781   W (ret);
9782   return ret;
9783 }
9784
9785 static int
9786 api_ip6nd_proxy_dump (vat_main_t * vam)
9787 {
9788   vl_api_ip6nd_proxy_dump_t *mp;
9789   vl_api_control_ping_t *mp_ping;
9790   int ret;
9791
9792   M (IP6ND_PROXY_DUMP, mp);
9793
9794   S (mp);
9795
9796   /* Use a control ping for synchronization */
9797   MPING (CONTROL_PING, mp_ping);
9798   S (mp_ping);
9799
9800   W (ret);
9801   return ret;
9802 }
9803
9804 static void vl_api_ip6nd_proxy_details_t_handler
9805   (vl_api_ip6nd_proxy_details_t * mp)
9806 {
9807   vat_main_t *vam = &vat_main;
9808
9809   print (vam->ofp, "host %U sw_if_index %d",
9810          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9811 }
9812
9813 static void vl_api_ip6nd_proxy_details_t_handler_json
9814   (vl_api_ip6nd_proxy_details_t * mp)
9815 {
9816   vat_main_t *vam = &vat_main;
9817   struct in6_addr ip6;
9818   vat_json_node_t *node = NULL;
9819
9820   if (VAT_JSON_ARRAY != vam->json_tree.type)
9821     {
9822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9823       vat_json_init_array (&vam->json_tree);
9824     }
9825   node = vat_json_array_add (&vam->json_tree);
9826
9827   vat_json_init_object (node);
9828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9829
9830   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9831   vat_json_object_add_ip6 (node, "host", ip6);
9832 }
9833
9834 static int
9835 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9836 {
9837   unformat_input_t *i = vam->input;
9838   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9839   u32 sw_if_index;
9840   u8 sw_if_index_set = 0;
9841   u32 address_length = 0;
9842   u8 v6_address_set = 0;
9843   ip6_address_t v6address;
9844   u8 use_default = 0;
9845   u8 no_advertise = 0;
9846   u8 off_link = 0;
9847   u8 no_autoconfig = 0;
9848   u8 no_onlink = 0;
9849   u8 is_no = 0;
9850   u32 val_lifetime = 0;
9851   u32 pref_lifetime = 0;
9852   int ret;
9853
9854   /* Parse args required to build the message */
9855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9858         sw_if_index_set = 1;
9859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9860         sw_if_index_set = 1;
9861       else if (unformat (i, "%U/%d",
9862                          unformat_ip6_address, &v6address, &address_length))
9863         v6_address_set = 1;
9864       else if (unformat (i, "val_life %d", &val_lifetime))
9865         ;
9866       else if (unformat (i, "pref_life %d", &pref_lifetime))
9867         ;
9868       else if (unformat (i, "def"))
9869         use_default = 1;
9870       else if (unformat (i, "noadv"))
9871         no_advertise = 1;
9872       else if (unformat (i, "offl"))
9873         off_link = 1;
9874       else if (unformat (i, "noauto"))
9875         no_autoconfig = 1;
9876       else if (unformat (i, "nolink"))
9877         no_onlink = 1;
9878       else if (unformat (i, "isno"))
9879         is_no = 1;
9880       else
9881         {
9882           clib_warning ("parse error '%U'", format_unformat_error, i);
9883           return -99;
9884         }
9885     }
9886
9887   if (sw_if_index_set == 0)
9888     {
9889       errmsg ("missing interface name or sw_if_index");
9890       return -99;
9891     }
9892   if (!v6_address_set)
9893     {
9894       errmsg ("no address set");
9895       return -99;
9896     }
9897
9898   /* Construct the API message */
9899   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9900
9901   mp->sw_if_index = ntohl (sw_if_index);
9902   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9903   mp->address_length = address_length;
9904   mp->use_default = use_default;
9905   mp->no_advertise = no_advertise;
9906   mp->off_link = off_link;
9907   mp->no_autoconfig = no_autoconfig;
9908   mp->no_onlink = no_onlink;
9909   mp->is_no = is_no;
9910   mp->val_lifetime = ntohl (val_lifetime);
9911   mp->pref_lifetime = ntohl (pref_lifetime);
9912
9913   /* send it... */
9914   S (mp);
9915
9916   /* Wait for a reply, return good/bad news  */
9917   W (ret);
9918   return ret;
9919 }
9920
9921 static int
9922 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9923 {
9924   unformat_input_t *i = vam->input;
9925   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9926   u32 sw_if_index;
9927   u8 sw_if_index_set = 0;
9928   u8 suppress = 0;
9929   u8 managed = 0;
9930   u8 other = 0;
9931   u8 ll_option = 0;
9932   u8 send_unicast = 0;
9933   u8 cease = 0;
9934   u8 is_no = 0;
9935   u8 default_router = 0;
9936   u32 max_interval = 0;
9937   u32 min_interval = 0;
9938   u32 lifetime = 0;
9939   u32 initial_count = 0;
9940   u32 initial_interval = 0;
9941   int ret;
9942
9943
9944   /* Parse args required to build the message */
9945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9946     {
9947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9948         sw_if_index_set = 1;
9949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9950         sw_if_index_set = 1;
9951       else if (unformat (i, "maxint %d", &max_interval))
9952         ;
9953       else if (unformat (i, "minint %d", &min_interval))
9954         ;
9955       else if (unformat (i, "life %d", &lifetime))
9956         ;
9957       else if (unformat (i, "count %d", &initial_count))
9958         ;
9959       else if (unformat (i, "interval %d", &initial_interval))
9960         ;
9961       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9962         suppress = 1;
9963       else if (unformat (i, "managed"))
9964         managed = 1;
9965       else if (unformat (i, "other"))
9966         other = 1;
9967       else if (unformat (i, "ll"))
9968         ll_option = 1;
9969       else if (unformat (i, "send"))
9970         send_unicast = 1;
9971       else if (unformat (i, "cease"))
9972         cease = 1;
9973       else if (unformat (i, "isno"))
9974         is_no = 1;
9975       else if (unformat (i, "def"))
9976         default_router = 1;
9977       else
9978         {
9979           clib_warning ("parse error '%U'", format_unformat_error, i);
9980           return -99;
9981         }
9982     }
9983
9984   if (sw_if_index_set == 0)
9985     {
9986       errmsg ("missing interface name or sw_if_index");
9987       return -99;
9988     }
9989
9990   /* Construct the API message */
9991   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9992
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   mp->max_interval = ntohl (max_interval);
9995   mp->min_interval = ntohl (min_interval);
9996   mp->lifetime = ntohl (lifetime);
9997   mp->initial_count = ntohl (initial_count);
9998   mp->initial_interval = ntohl (initial_interval);
9999   mp->suppress = suppress;
10000   mp->managed = managed;
10001   mp->other = other;
10002   mp->ll_option = ll_option;
10003   mp->send_unicast = send_unicast;
10004   mp->cease = cease;
10005   mp->is_no = is_no;
10006   mp->default_router = default_router;
10007
10008   /* send it... */
10009   S (mp);
10010
10011   /* Wait for a reply, return good/bad news  */
10012   W (ret);
10013   return ret;
10014 }
10015
10016 static int
10017 api_set_arp_neighbor_limit (vat_main_t * vam)
10018 {
10019   unformat_input_t *i = vam->input;
10020   vl_api_set_arp_neighbor_limit_t *mp;
10021   u32 arp_nbr_limit;
10022   u8 limit_set = 0;
10023   u8 is_ipv6 = 0;
10024   int ret;
10025
10026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10027     {
10028       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10029         limit_set = 1;
10030       else if (unformat (i, "ipv6"))
10031         is_ipv6 = 1;
10032       else
10033         {
10034           clib_warning ("parse error '%U'", format_unformat_error, i);
10035           return -99;
10036         }
10037     }
10038
10039   if (limit_set == 0)
10040     {
10041       errmsg ("missing limit value");
10042       return -99;
10043     }
10044
10045   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10046
10047   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10048   mp->is_ipv6 = is_ipv6;
10049
10050   S (mp);
10051   W (ret);
10052   return ret;
10053 }
10054
10055 static int
10056 api_l2_patch_add_del (vat_main_t * vam)
10057 {
10058   unformat_input_t *i = vam->input;
10059   vl_api_l2_patch_add_del_t *mp;
10060   u32 rx_sw_if_index;
10061   u8 rx_sw_if_index_set = 0;
10062   u32 tx_sw_if_index;
10063   u8 tx_sw_if_index_set = 0;
10064   u8 is_add = 1;
10065   int ret;
10066
10067   /* Parse args required to build the message */
10068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10069     {
10070       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10071         rx_sw_if_index_set = 1;
10072       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10073         tx_sw_if_index_set = 1;
10074       else if (unformat (i, "rx"))
10075         {
10076           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10077             {
10078               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10079                             &rx_sw_if_index))
10080                 rx_sw_if_index_set = 1;
10081             }
10082           else
10083             break;
10084         }
10085       else if (unformat (i, "tx"))
10086         {
10087           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10088             {
10089               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10090                             &tx_sw_if_index))
10091                 tx_sw_if_index_set = 1;
10092             }
10093           else
10094             break;
10095         }
10096       else if (unformat (i, "del"))
10097         is_add = 0;
10098       else
10099         break;
10100     }
10101
10102   if (rx_sw_if_index_set == 0)
10103     {
10104       errmsg ("missing rx interface name or rx_sw_if_index");
10105       return -99;
10106     }
10107
10108   if (tx_sw_if_index_set == 0)
10109     {
10110       errmsg ("missing tx interface name or tx_sw_if_index");
10111       return -99;
10112     }
10113
10114   M (L2_PATCH_ADD_DEL, mp);
10115
10116   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10117   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10118   mp->is_add = is_add;
10119
10120   S (mp);
10121   W (ret);
10122   return ret;
10123 }
10124
10125 u8 is_del;
10126 u8 localsid_addr[16];
10127 u8 end_psp;
10128 u8 behavior;
10129 u32 sw_if_index;
10130 u32 vlan_index;
10131 u32 fib_table;
10132 u8 nh_addr[16];
10133
10134 static int
10135 api_sr_localsid_add_del (vat_main_t * vam)
10136 {
10137   unformat_input_t *i = vam->input;
10138   vl_api_sr_localsid_add_del_t *mp;
10139
10140   u8 is_del;
10141   ip6_address_t localsid;
10142   u8 end_psp = 0;
10143   u8 behavior = ~0;
10144   u32 sw_if_index;
10145   u32 fib_table = ~(u32) 0;
10146   ip6_address_t next_hop;
10147
10148   bool nexthop_set = 0;
10149
10150   int ret;
10151
10152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10153     {
10154       if (unformat (i, "del"))
10155         is_del = 1;
10156       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10157       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10158         nexthop_set = 1;
10159       else if (unformat (i, "behavior %u", &behavior));
10160       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10161       else if (unformat (i, "fib-table %u", &fib_table));
10162       else if (unformat (i, "end.psp %u", &behavior));
10163       else
10164         break;
10165     }
10166
10167   M (SR_LOCALSID_ADD_DEL, mp);
10168
10169   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10170   if (nexthop_set)
10171     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10172   mp->behavior = behavior;
10173   mp->sw_if_index = ntohl (sw_if_index);
10174   mp->fib_table = ntohl (fib_table);
10175   mp->end_psp = end_psp;
10176   mp->is_del = is_del;
10177
10178   S (mp);
10179   W (ret);
10180   return ret;
10181 }
10182
10183 static int
10184 api_ioam_enable (vat_main_t * vam)
10185 {
10186   unformat_input_t *input = vam->input;
10187   vl_api_ioam_enable_t *mp;
10188   u32 id = 0;
10189   int has_trace_option = 0;
10190   int has_pot_option = 0;
10191   int has_seqno_option = 0;
10192   int has_analyse_option = 0;
10193   int ret;
10194
10195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10196     {
10197       if (unformat (input, "trace"))
10198         has_trace_option = 1;
10199       else if (unformat (input, "pot"))
10200         has_pot_option = 1;
10201       else if (unformat (input, "seqno"))
10202         has_seqno_option = 1;
10203       else if (unformat (input, "analyse"))
10204         has_analyse_option = 1;
10205       else
10206         break;
10207     }
10208   M (IOAM_ENABLE, mp);
10209   mp->id = htons (id);
10210   mp->seqno = has_seqno_option;
10211   mp->analyse = has_analyse_option;
10212   mp->pot_enable = has_pot_option;
10213   mp->trace_enable = has_trace_option;
10214
10215   S (mp);
10216   W (ret);
10217   return ret;
10218 }
10219
10220
10221 static int
10222 api_ioam_disable (vat_main_t * vam)
10223 {
10224   vl_api_ioam_disable_t *mp;
10225   int ret;
10226
10227   M (IOAM_DISABLE, mp);
10228   S (mp);
10229   W (ret);
10230   return ret;
10231 }
10232
10233 #define foreach_tcp_proto_field                 \
10234 _(src_port)                                     \
10235 _(dst_port)
10236
10237 #define foreach_udp_proto_field                 \
10238 _(src_port)                                     \
10239 _(dst_port)
10240
10241 #define foreach_ip4_proto_field                 \
10242 _(src_address)                                  \
10243 _(dst_address)                                  \
10244 _(tos)                                          \
10245 _(length)                                       \
10246 _(fragment_id)                                  \
10247 _(ttl)                                          \
10248 _(protocol)                                     \
10249 _(checksum)
10250
10251 typedef struct
10252 {
10253   u16 src_port, dst_port;
10254 } tcpudp_header_t;
10255
10256 #if VPP_API_TEST_BUILTIN == 0
10257 uword
10258 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10259 {
10260   u8 **maskp = va_arg (*args, u8 **);
10261   u8 *mask = 0;
10262   u8 found_something = 0;
10263   tcp_header_t *tcp;
10264
10265 #define _(a) u8 a=0;
10266   foreach_tcp_proto_field;
10267 #undef _
10268
10269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10270     {
10271       if (0);
10272 #define _(a) else if (unformat (input, #a)) a=1;
10273       foreach_tcp_proto_field
10274 #undef _
10275         else
10276         break;
10277     }
10278
10279 #define _(a) found_something += a;
10280   foreach_tcp_proto_field;
10281 #undef _
10282
10283   if (found_something == 0)
10284     return 0;
10285
10286   vec_validate (mask, sizeof (*tcp) - 1);
10287
10288   tcp = (tcp_header_t *) mask;
10289
10290 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10291   foreach_tcp_proto_field;
10292 #undef _
10293
10294   *maskp = mask;
10295   return 1;
10296 }
10297
10298 uword
10299 unformat_udp_mask (unformat_input_t * input, va_list * args)
10300 {
10301   u8 **maskp = va_arg (*args, u8 **);
10302   u8 *mask = 0;
10303   u8 found_something = 0;
10304   udp_header_t *udp;
10305
10306 #define _(a) u8 a=0;
10307   foreach_udp_proto_field;
10308 #undef _
10309
10310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (0);
10313 #define _(a) else if (unformat (input, #a)) a=1;
10314       foreach_udp_proto_field
10315 #undef _
10316         else
10317         break;
10318     }
10319
10320 #define _(a) found_something += a;
10321   foreach_udp_proto_field;
10322 #undef _
10323
10324   if (found_something == 0)
10325     return 0;
10326
10327   vec_validate (mask, sizeof (*udp) - 1);
10328
10329   udp = (udp_header_t *) mask;
10330
10331 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10332   foreach_udp_proto_field;
10333 #undef _
10334
10335   *maskp = mask;
10336   return 1;
10337 }
10338
10339 uword
10340 unformat_l4_mask (unformat_input_t * input, va_list * args)
10341 {
10342   u8 **maskp = va_arg (*args, u8 **);
10343   u16 src_port = 0, dst_port = 0;
10344   tcpudp_header_t *tcpudp;
10345
10346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10347     {
10348       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10349         return 1;
10350       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10351         return 1;
10352       else if (unformat (input, "src_port"))
10353         src_port = 0xFFFF;
10354       else if (unformat (input, "dst_port"))
10355         dst_port = 0xFFFF;
10356       else
10357         return 0;
10358     }
10359
10360   if (!src_port && !dst_port)
10361     return 0;
10362
10363   u8 *mask = 0;
10364   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10365
10366   tcpudp = (tcpudp_header_t *) mask;
10367   tcpudp->src_port = src_port;
10368   tcpudp->dst_port = dst_port;
10369
10370   *maskp = mask;
10371
10372   return 1;
10373 }
10374
10375 uword
10376 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10377 {
10378   u8 **maskp = va_arg (*args, u8 **);
10379   u8 *mask = 0;
10380   u8 found_something = 0;
10381   ip4_header_t *ip;
10382
10383 #define _(a) u8 a=0;
10384   foreach_ip4_proto_field;
10385 #undef _
10386   u8 version = 0;
10387   u8 hdr_length = 0;
10388
10389
10390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10391     {
10392       if (unformat (input, "version"))
10393         version = 1;
10394       else if (unformat (input, "hdr_length"))
10395         hdr_length = 1;
10396       else if (unformat (input, "src"))
10397         src_address = 1;
10398       else if (unformat (input, "dst"))
10399         dst_address = 1;
10400       else if (unformat (input, "proto"))
10401         protocol = 1;
10402
10403 #define _(a) else if (unformat (input, #a)) a=1;
10404       foreach_ip4_proto_field
10405 #undef _
10406         else
10407         break;
10408     }
10409
10410 #define _(a) found_something += a;
10411   foreach_ip4_proto_field;
10412 #undef _
10413
10414   if (found_something == 0)
10415     return 0;
10416
10417   vec_validate (mask, sizeof (*ip) - 1);
10418
10419   ip = (ip4_header_t *) mask;
10420
10421 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10422   foreach_ip4_proto_field;
10423 #undef _
10424
10425   ip->ip_version_and_header_length = 0;
10426
10427   if (version)
10428     ip->ip_version_and_header_length |= 0xF0;
10429
10430   if (hdr_length)
10431     ip->ip_version_and_header_length |= 0x0F;
10432
10433   *maskp = mask;
10434   return 1;
10435 }
10436
10437 #define foreach_ip6_proto_field                 \
10438 _(src_address)                                  \
10439 _(dst_address)                                  \
10440 _(payload_length)                               \
10441 _(hop_limit)                                    \
10442 _(protocol)
10443
10444 uword
10445 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10446 {
10447   u8 **maskp = va_arg (*args, u8 **);
10448   u8 *mask = 0;
10449   u8 found_something = 0;
10450   ip6_header_t *ip;
10451   u32 ip_version_traffic_class_and_flow_label;
10452
10453 #define _(a) u8 a=0;
10454   foreach_ip6_proto_field;
10455 #undef _
10456   u8 version = 0;
10457   u8 traffic_class = 0;
10458   u8 flow_label = 0;
10459
10460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10461     {
10462       if (unformat (input, "version"))
10463         version = 1;
10464       else if (unformat (input, "traffic-class"))
10465         traffic_class = 1;
10466       else if (unformat (input, "flow-label"))
10467         flow_label = 1;
10468       else if (unformat (input, "src"))
10469         src_address = 1;
10470       else if (unformat (input, "dst"))
10471         dst_address = 1;
10472       else if (unformat (input, "proto"))
10473         protocol = 1;
10474
10475 #define _(a) else if (unformat (input, #a)) a=1;
10476       foreach_ip6_proto_field
10477 #undef _
10478         else
10479         break;
10480     }
10481
10482 #define _(a) found_something += a;
10483   foreach_ip6_proto_field;
10484 #undef _
10485
10486   if (found_something == 0)
10487     return 0;
10488
10489   vec_validate (mask, sizeof (*ip) - 1);
10490
10491   ip = (ip6_header_t *) mask;
10492
10493 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10494   foreach_ip6_proto_field;
10495 #undef _
10496
10497   ip_version_traffic_class_and_flow_label = 0;
10498
10499   if (version)
10500     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10501
10502   if (traffic_class)
10503     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10504
10505   if (flow_label)
10506     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10507
10508   ip->ip_version_traffic_class_and_flow_label =
10509     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10510
10511   *maskp = mask;
10512   return 1;
10513 }
10514
10515 uword
10516 unformat_l3_mask (unformat_input_t * input, va_list * args)
10517 {
10518   u8 **maskp = va_arg (*args, u8 **);
10519
10520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10521     {
10522       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10523         return 1;
10524       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10525         return 1;
10526       else
10527         break;
10528     }
10529   return 0;
10530 }
10531
10532 uword
10533 unformat_l2_mask (unformat_input_t * input, va_list * args)
10534 {
10535   u8 **maskp = va_arg (*args, u8 **);
10536   u8 *mask = 0;
10537   u8 src = 0;
10538   u8 dst = 0;
10539   u8 proto = 0;
10540   u8 tag1 = 0;
10541   u8 tag2 = 0;
10542   u8 ignore_tag1 = 0;
10543   u8 ignore_tag2 = 0;
10544   u8 cos1 = 0;
10545   u8 cos2 = 0;
10546   u8 dot1q = 0;
10547   u8 dot1ad = 0;
10548   int len = 14;
10549
10550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (input, "src"))
10553         src = 1;
10554       else if (unformat (input, "dst"))
10555         dst = 1;
10556       else if (unformat (input, "proto"))
10557         proto = 1;
10558       else if (unformat (input, "tag1"))
10559         tag1 = 1;
10560       else if (unformat (input, "tag2"))
10561         tag2 = 1;
10562       else if (unformat (input, "ignore-tag1"))
10563         ignore_tag1 = 1;
10564       else if (unformat (input, "ignore-tag2"))
10565         ignore_tag2 = 1;
10566       else if (unformat (input, "cos1"))
10567         cos1 = 1;
10568       else if (unformat (input, "cos2"))
10569         cos2 = 1;
10570       else if (unformat (input, "dot1q"))
10571         dot1q = 1;
10572       else if (unformat (input, "dot1ad"))
10573         dot1ad = 1;
10574       else
10575         break;
10576     }
10577   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10578        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10579     return 0;
10580
10581   if (tag1 || ignore_tag1 || cos1 || dot1q)
10582     len = 18;
10583   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10584     len = 22;
10585
10586   vec_validate (mask, len - 1);
10587
10588   if (dst)
10589     memset (mask, 0xff, 6);
10590
10591   if (src)
10592     memset (mask + 6, 0xff, 6);
10593
10594   if (tag2 || dot1ad)
10595     {
10596       /* inner vlan tag */
10597       if (tag2)
10598         {
10599           mask[19] = 0xff;
10600           mask[18] = 0x0f;
10601         }
10602       if (cos2)
10603         mask[18] |= 0xe0;
10604       if (proto)
10605         mask[21] = mask[20] = 0xff;
10606       if (tag1)
10607         {
10608           mask[15] = 0xff;
10609           mask[14] = 0x0f;
10610         }
10611       if (cos1)
10612         mask[14] |= 0xe0;
10613       *maskp = mask;
10614       return 1;
10615     }
10616   if (tag1 | dot1q)
10617     {
10618       if (tag1)
10619         {
10620           mask[15] = 0xff;
10621           mask[14] = 0x0f;
10622         }
10623       if (cos1)
10624         mask[14] |= 0xe0;
10625       if (proto)
10626         mask[16] = mask[17] = 0xff;
10627
10628       *maskp = mask;
10629       return 1;
10630     }
10631   if (cos2)
10632     mask[18] |= 0xe0;
10633   if (cos1)
10634     mask[14] |= 0xe0;
10635   if (proto)
10636     mask[12] = mask[13] = 0xff;
10637
10638   *maskp = mask;
10639   return 1;
10640 }
10641
10642 uword
10643 unformat_classify_mask (unformat_input_t * input, va_list * args)
10644 {
10645   u8 **maskp = va_arg (*args, u8 **);
10646   u32 *skipp = va_arg (*args, u32 *);
10647   u32 *matchp = va_arg (*args, u32 *);
10648   u32 match;
10649   u8 *mask = 0;
10650   u8 *l2 = 0;
10651   u8 *l3 = 0;
10652   u8 *l4 = 0;
10653   int i;
10654
10655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10658         ;
10659       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10660         ;
10661       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10662         ;
10663       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10664         ;
10665       else
10666         break;
10667     }
10668
10669   if (l4 && !l3)
10670     {
10671       vec_free (mask);
10672       vec_free (l2);
10673       vec_free (l4);
10674       return 0;
10675     }
10676
10677   if (mask || l2 || l3 || l4)
10678     {
10679       if (l2 || l3 || l4)
10680         {
10681           /* "With a free Ethernet header in every package" */
10682           if (l2 == 0)
10683             vec_validate (l2, 13);
10684           mask = l2;
10685           if (vec_len (l3))
10686             {
10687               vec_append (mask, l3);
10688               vec_free (l3);
10689             }
10690           if (vec_len (l4))
10691             {
10692               vec_append (mask, l4);
10693               vec_free (l4);
10694             }
10695         }
10696
10697       /* Scan forward looking for the first significant mask octet */
10698       for (i = 0; i < vec_len (mask); i++)
10699         if (mask[i])
10700           break;
10701
10702       /* compute (skip, match) params */
10703       *skipp = i / sizeof (u32x4);
10704       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10705
10706       /* Pad mask to an even multiple of the vector size */
10707       while (vec_len (mask) % sizeof (u32x4))
10708         vec_add1 (mask, 0);
10709
10710       match = vec_len (mask) / sizeof (u32x4);
10711
10712       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10713         {
10714           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10715           if (*tmp || *(tmp + 1))
10716             break;
10717           match--;
10718         }
10719       if (match == 0)
10720         clib_warning ("BUG: match 0");
10721
10722       _vec_len (mask) = match * sizeof (u32x4);
10723
10724       *matchp = match;
10725       *maskp = mask;
10726
10727       return 1;
10728     }
10729
10730   return 0;
10731 }
10732 #endif /* VPP_API_TEST_BUILTIN */
10733
10734 #define foreach_l2_next                         \
10735 _(drop, DROP)                                   \
10736 _(ethernet, ETHERNET_INPUT)                     \
10737 _(ip4, IP4_INPUT)                               \
10738 _(ip6, IP6_INPUT)
10739
10740 uword
10741 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10742 {
10743   u32 *miss_next_indexp = va_arg (*args, u32 *);
10744   u32 next_index = 0;
10745   u32 tmp;
10746
10747 #define _(n,N) \
10748   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10749   foreach_l2_next;
10750 #undef _
10751
10752   if (unformat (input, "%d", &tmp))
10753     {
10754       next_index = tmp;
10755       goto out;
10756     }
10757
10758   return 0;
10759
10760 out:
10761   *miss_next_indexp = next_index;
10762   return 1;
10763 }
10764
10765 #define foreach_ip_next                         \
10766 _(drop, DROP)                                   \
10767 _(local, LOCAL)                                 \
10768 _(rewrite, REWRITE)
10769
10770 uword
10771 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10772 {
10773   u32 *miss_next_indexp = va_arg (*args, u32 *);
10774   u32 next_index = 0;
10775   u32 tmp;
10776
10777 #define _(n,N) \
10778   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10779   foreach_ip_next;
10780 #undef _
10781
10782   if (unformat (input, "%d", &tmp))
10783     {
10784       next_index = tmp;
10785       goto out;
10786     }
10787
10788   return 0;
10789
10790 out:
10791   *miss_next_indexp = next_index;
10792   return 1;
10793 }
10794
10795 #define foreach_acl_next                        \
10796 _(deny, DENY)
10797
10798 uword
10799 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10800 {
10801   u32 *miss_next_indexp = va_arg (*args, u32 *);
10802   u32 next_index = 0;
10803   u32 tmp;
10804
10805 #define _(n,N) \
10806   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10807   foreach_acl_next;
10808 #undef _
10809
10810   if (unformat (input, "permit"))
10811     {
10812       next_index = ~0;
10813       goto out;
10814     }
10815   else if (unformat (input, "%d", &tmp))
10816     {
10817       next_index = tmp;
10818       goto out;
10819     }
10820
10821   return 0;
10822
10823 out:
10824   *miss_next_indexp = next_index;
10825   return 1;
10826 }
10827
10828 uword
10829 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10830 {
10831   u32 *r = va_arg (*args, u32 *);
10832
10833   if (unformat (input, "conform-color"))
10834     *r = POLICE_CONFORM;
10835   else if (unformat (input, "exceed-color"))
10836     *r = POLICE_EXCEED;
10837   else
10838     return 0;
10839
10840   return 1;
10841 }
10842
10843 static int
10844 api_classify_add_del_table (vat_main_t * vam)
10845 {
10846   unformat_input_t *i = vam->input;
10847   vl_api_classify_add_del_table_t *mp;
10848
10849   u32 nbuckets = 2;
10850   u32 skip = ~0;
10851   u32 match = ~0;
10852   int is_add = 1;
10853   int del_chain = 0;
10854   u32 table_index = ~0;
10855   u32 next_table_index = ~0;
10856   u32 miss_next_index = ~0;
10857   u32 memory_size = 32 << 20;
10858   u8 *mask = 0;
10859   u32 current_data_flag = 0;
10860   int current_data_offset = 0;
10861   int ret;
10862
10863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10864     {
10865       if (unformat (i, "del"))
10866         is_add = 0;
10867       else if (unformat (i, "del-chain"))
10868         {
10869           is_add = 0;
10870           del_chain = 1;
10871         }
10872       else if (unformat (i, "buckets %d", &nbuckets))
10873         ;
10874       else if (unformat (i, "memory_size %d", &memory_size))
10875         ;
10876       else if (unformat (i, "skip %d", &skip))
10877         ;
10878       else if (unformat (i, "match %d", &match))
10879         ;
10880       else if (unformat (i, "table %d", &table_index))
10881         ;
10882       else if (unformat (i, "mask %U", unformat_classify_mask,
10883                          &mask, &skip, &match))
10884         ;
10885       else if (unformat (i, "next-table %d", &next_table_index))
10886         ;
10887       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10888                          &miss_next_index))
10889         ;
10890       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10891                          &miss_next_index))
10892         ;
10893       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10894                          &miss_next_index))
10895         ;
10896       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10897         ;
10898       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10899         ;
10900       else
10901         break;
10902     }
10903
10904   if (is_add && mask == 0)
10905     {
10906       errmsg ("Mask required");
10907       return -99;
10908     }
10909
10910   if (is_add && skip == ~0)
10911     {
10912       errmsg ("skip count required");
10913       return -99;
10914     }
10915
10916   if (is_add && match == ~0)
10917     {
10918       errmsg ("match count required");
10919       return -99;
10920     }
10921
10922   if (!is_add && table_index == ~0)
10923     {
10924       errmsg ("table index required for delete");
10925       return -99;
10926     }
10927
10928   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10929
10930   mp->is_add = is_add;
10931   mp->del_chain = del_chain;
10932   mp->table_index = ntohl (table_index);
10933   mp->nbuckets = ntohl (nbuckets);
10934   mp->memory_size = ntohl (memory_size);
10935   mp->skip_n_vectors = ntohl (skip);
10936   mp->match_n_vectors = ntohl (match);
10937   mp->next_table_index = ntohl (next_table_index);
10938   mp->miss_next_index = ntohl (miss_next_index);
10939   mp->current_data_flag = ntohl (current_data_flag);
10940   mp->current_data_offset = ntohl (current_data_offset);
10941   clib_memcpy (mp->mask, mask, vec_len (mask));
10942
10943   vec_free (mask);
10944
10945   S (mp);
10946   W (ret);
10947   return ret;
10948 }
10949
10950 #if VPP_API_TEST_BUILTIN == 0
10951 uword
10952 unformat_l4_match (unformat_input_t * input, va_list * args)
10953 {
10954   u8 **matchp = va_arg (*args, u8 **);
10955
10956   u8 *proto_header = 0;
10957   int src_port = 0;
10958   int dst_port = 0;
10959
10960   tcpudp_header_t h;
10961
10962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10963     {
10964       if (unformat (input, "src_port %d", &src_port))
10965         ;
10966       else if (unformat (input, "dst_port %d", &dst_port))
10967         ;
10968       else
10969         return 0;
10970     }
10971
10972   h.src_port = clib_host_to_net_u16 (src_port);
10973   h.dst_port = clib_host_to_net_u16 (dst_port);
10974   vec_validate (proto_header, sizeof (h) - 1);
10975   memcpy (proto_header, &h, sizeof (h));
10976
10977   *matchp = proto_header;
10978
10979   return 1;
10980 }
10981
10982 uword
10983 unformat_ip4_match (unformat_input_t * input, va_list * args)
10984 {
10985   u8 **matchp = va_arg (*args, u8 **);
10986   u8 *match = 0;
10987   ip4_header_t *ip;
10988   int version = 0;
10989   u32 version_val;
10990   int hdr_length = 0;
10991   u32 hdr_length_val;
10992   int src = 0, dst = 0;
10993   ip4_address_t src_val, dst_val;
10994   int proto = 0;
10995   u32 proto_val;
10996   int tos = 0;
10997   u32 tos_val;
10998   int length = 0;
10999   u32 length_val;
11000   int fragment_id = 0;
11001   u32 fragment_id_val;
11002   int ttl = 0;
11003   int ttl_val;
11004   int checksum = 0;
11005   u32 checksum_val;
11006
11007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11008     {
11009       if (unformat (input, "version %d", &version_val))
11010         version = 1;
11011       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11012         hdr_length = 1;
11013       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11014         src = 1;
11015       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11016         dst = 1;
11017       else if (unformat (input, "proto %d", &proto_val))
11018         proto = 1;
11019       else if (unformat (input, "tos %d", &tos_val))
11020         tos = 1;
11021       else if (unformat (input, "length %d", &length_val))
11022         length = 1;
11023       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11024         fragment_id = 1;
11025       else if (unformat (input, "ttl %d", &ttl_val))
11026         ttl = 1;
11027       else if (unformat (input, "checksum %d", &checksum_val))
11028         checksum = 1;
11029       else
11030         break;
11031     }
11032
11033   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11034       + ttl + checksum == 0)
11035     return 0;
11036
11037   /*
11038    * Aligned because we use the real comparison functions
11039    */
11040   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11041
11042   ip = (ip4_header_t *) match;
11043
11044   /* These are realistically matched in practice */
11045   if (src)
11046     ip->src_address.as_u32 = src_val.as_u32;
11047
11048   if (dst)
11049     ip->dst_address.as_u32 = dst_val.as_u32;
11050
11051   if (proto)
11052     ip->protocol = proto_val;
11053
11054
11055   /* These are not, but they're included for completeness */
11056   if (version)
11057     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11058
11059   if (hdr_length)
11060     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11061
11062   if (tos)
11063     ip->tos = tos_val;
11064
11065   if (length)
11066     ip->length = clib_host_to_net_u16 (length_val);
11067
11068   if (ttl)
11069     ip->ttl = ttl_val;
11070
11071   if (checksum)
11072     ip->checksum = clib_host_to_net_u16 (checksum_val);
11073
11074   *matchp = match;
11075   return 1;
11076 }
11077
11078 uword
11079 unformat_ip6_match (unformat_input_t * input, va_list * args)
11080 {
11081   u8 **matchp = va_arg (*args, u8 **);
11082   u8 *match = 0;
11083   ip6_header_t *ip;
11084   int version = 0;
11085   u32 version_val;
11086   u8 traffic_class = 0;
11087   u32 traffic_class_val = 0;
11088   u8 flow_label = 0;
11089   u8 flow_label_val;
11090   int src = 0, dst = 0;
11091   ip6_address_t src_val, dst_val;
11092   int proto = 0;
11093   u32 proto_val;
11094   int payload_length = 0;
11095   u32 payload_length_val;
11096   int hop_limit = 0;
11097   int hop_limit_val;
11098   u32 ip_version_traffic_class_and_flow_label;
11099
11100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11101     {
11102       if (unformat (input, "version %d", &version_val))
11103         version = 1;
11104       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11105         traffic_class = 1;
11106       else if (unformat (input, "flow_label %d", &flow_label_val))
11107         flow_label = 1;
11108       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11109         src = 1;
11110       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11111         dst = 1;
11112       else if (unformat (input, "proto %d", &proto_val))
11113         proto = 1;
11114       else if (unformat (input, "payload_length %d", &payload_length_val))
11115         payload_length = 1;
11116       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11117         hop_limit = 1;
11118       else
11119         break;
11120     }
11121
11122   if (version + traffic_class + flow_label + src + dst + proto +
11123       payload_length + hop_limit == 0)
11124     return 0;
11125
11126   /*
11127    * Aligned because we use the real comparison functions
11128    */
11129   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11130
11131   ip = (ip6_header_t *) match;
11132
11133   if (src)
11134     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11135
11136   if (dst)
11137     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11138
11139   if (proto)
11140     ip->protocol = proto_val;
11141
11142   ip_version_traffic_class_and_flow_label = 0;
11143
11144   if (version)
11145     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11146
11147   if (traffic_class)
11148     ip_version_traffic_class_and_flow_label |=
11149       (traffic_class_val & 0xFF) << 20;
11150
11151   if (flow_label)
11152     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11153
11154   ip->ip_version_traffic_class_and_flow_label =
11155     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11156
11157   if (payload_length)
11158     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11159
11160   if (hop_limit)
11161     ip->hop_limit = hop_limit_val;
11162
11163   *matchp = match;
11164   return 1;
11165 }
11166
11167 uword
11168 unformat_l3_match (unformat_input_t * input, va_list * args)
11169 {
11170   u8 **matchp = va_arg (*args, u8 **);
11171
11172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11173     {
11174       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11175         return 1;
11176       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11177         return 1;
11178       else
11179         break;
11180     }
11181   return 0;
11182 }
11183
11184 uword
11185 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11186 {
11187   u8 *tagp = va_arg (*args, u8 *);
11188   u32 tag;
11189
11190   if (unformat (input, "%d", &tag))
11191     {
11192       tagp[0] = (tag >> 8) & 0x0F;
11193       tagp[1] = tag & 0xFF;
11194       return 1;
11195     }
11196
11197   return 0;
11198 }
11199
11200 uword
11201 unformat_l2_match (unformat_input_t * input, va_list * args)
11202 {
11203   u8 **matchp = va_arg (*args, u8 **);
11204   u8 *match = 0;
11205   u8 src = 0;
11206   u8 src_val[6];
11207   u8 dst = 0;
11208   u8 dst_val[6];
11209   u8 proto = 0;
11210   u16 proto_val;
11211   u8 tag1 = 0;
11212   u8 tag1_val[2];
11213   u8 tag2 = 0;
11214   u8 tag2_val[2];
11215   int len = 14;
11216   u8 ignore_tag1 = 0;
11217   u8 ignore_tag2 = 0;
11218   u8 cos1 = 0;
11219   u8 cos2 = 0;
11220   u32 cos1_val = 0;
11221   u32 cos2_val = 0;
11222
11223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11224     {
11225       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11226         src = 1;
11227       else
11228         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11229         dst = 1;
11230       else if (unformat (input, "proto %U",
11231                          unformat_ethernet_type_host_byte_order, &proto_val))
11232         proto = 1;
11233       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11234         tag1 = 1;
11235       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11236         tag2 = 1;
11237       else if (unformat (input, "ignore-tag1"))
11238         ignore_tag1 = 1;
11239       else if (unformat (input, "ignore-tag2"))
11240         ignore_tag2 = 1;
11241       else if (unformat (input, "cos1 %d", &cos1_val))
11242         cos1 = 1;
11243       else if (unformat (input, "cos2 %d", &cos2_val))
11244         cos2 = 1;
11245       else
11246         break;
11247     }
11248   if ((src + dst + proto + tag1 + tag2 +
11249        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11250     return 0;
11251
11252   if (tag1 || ignore_tag1 || cos1)
11253     len = 18;
11254   if (tag2 || ignore_tag2 || cos2)
11255     len = 22;
11256
11257   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11258
11259   if (dst)
11260     clib_memcpy (match, dst_val, 6);
11261
11262   if (src)
11263     clib_memcpy (match + 6, src_val, 6);
11264
11265   if (tag2)
11266     {
11267       /* inner vlan tag */
11268       match[19] = tag2_val[1];
11269       match[18] = tag2_val[0];
11270       if (cos2)
11271         match[18] |= (cos2_val & 0x7) << 5;
11272       if (proto)
11273         {
11274           match[21] = proto_val & 0xff;
11275           match[20] = proto_val >> 8;
11276         }
11277       if (tag1)
11278         {
11279           match[15] = tag1_val[1];
11280           match[14] = tag1_val[0];
11281         }
11282       if (cos1)
11283         match[14] |= (cos1_val & 0x7) << 5;
11284       *matchp = match;
11285       return 1;
11286     }
11287   if (tag1)
11288     {
11289       match[15] = tag1_val[1];
11290       match[14] = tag1_val[0];
11291       if (proto)
11292         {
11293           match[17] = proto_val & 0xff;
11294           match[16] = proto_val >> 8;
11295         }
11296       if (cos1)
11297         match[14] |= (cos1_val & 0x7) << 5;
11298
11299       *matchp = match;
11300       return 1;
11301     }
11302   if (cos2)
11303     match[18] |= (cos2_val & 0x7) << 5;
11304   if (cos1)
11305     match[14] |= (cos1_val & 0x7) << 5;
11306   if (proto)
11307     {
11308       match[13] = proto_val & 0xff;
11309       match[12] = proto_val >> 8;
11310     }
11311
11312   *matchp = match;
11313   return 1;
11314 }
11315 #endif
11316
11317 uword
11318 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11319 {
11320   u8 **matchp = va_arg (*args, u8 **);
11321   u32 skip_n_vectors = va_arg (*args, u32);
11322   u32 match_n_vectors = va_arg (*args, u32);
11323
11324   u8 *match = 0;
11325   u8 *l2 = 0;
11326   u8 *l3 = 0;
11327   u8 *l4 = 0;
11328
11329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11330     {
11331       if (unformat (input, "hex %U", unformat_hex_string, &match))
11332         ;
11333       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11334         ;
11335       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11336         ;
11337       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11338         ;
11339       else
11340         break;
11341     }
11342
11343   if (l4 && !l3)
11344     {
11345       vec_free (match);
11346       vec_free (l2);
11347       vec_free (l4);
11348       return 0;
11349     }
11350
11351   if (match || l2 || l3 || l4)
11352     {
11353       if (l2 || l3 || l4)
11354         {
11355           /* "Win a free Ethernet header in every packet" */
11356           if (l2 == 0)
11357             vec_validate_aligned (l2, 13, sizeof (u32x4));
11358           match = l2;
11359           if (vec_len (l3))
11360             {
11361               vec_append_aligned (match, l3, sizeof (u32x4));
11362               vec_free (l3);
11363             }
11364           if (vec_len (l4))
11365             {
11366               vec_append_aligned (match, l4, sizeof (u32x4));
11367               vec_free (l4);
11368             }
11369         }
11370
11371       /* Make sure the vector is big enough even if key is all 0's */
11372       vec_validate_aligned
11373         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11374          sizeof (u32x4));
11375
11376       /* Set size, include skipped vectors */
11377       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11378
11379       *matchp = match;
11380
11381       return 1;
11382     }
11383
11384   return 0;
11385 }
11386
11387 static int
11388 api_classify_add_del_session (vat_main_t * vam)
11389 {
11390   unformat_input_t *i = vam->input;
11391   vl_api_classify_add_del_session_t *mp;
11392   int is_add = 1;
11393   u32 table_index = ~0;
11394   u32 hit_next_index = ~0;
11395   u32 opaque_index = ~0;
11396   u8 *match = 0;
11397   i32 advance = 0;
11398   u32 skip_n_vectors = 0;
11399   u32 match_n_vectors = 0;
11400   u32 action = 0;
11401   u32 metadata = 0;
11402   int ret;
11403
11404   /*
11405    * Warning: you have to supply skip_n and match_n
11406    * because the API client cant simply look at the classify
11407    * table object.
11408    */
11409
11410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11411     {
11412       if (unformat (i, "del"))
11413         is_add = 0;
11414       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11415                          &hit_next_index))
11416         ;
11417       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11418                          &hit_next_index))
11419         ;
11420       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11421                          &hit_next_index))
11422         ;
11423       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11424         ;
11425       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11426         ;
11427       else if (unformat (i, "opaque-index %d", &opaque_index))
11428         ;
11429       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11430         ;
11431       else if (unformat (i, "match_n %d", &match_n_vectors))
11432         ;
11433       else if (unformat (i, "match %U", api_unformat_classify_match,
11434                          &match, skip_n_vectors, match_n_vectors))
11435         ;
11436       else if (unformat (i, "advance %d", &advance))
11437         ;
11438       else if (unformat (i, "table-index %d", &table_index))
11439         ;
11440       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11441         action = 1;
11442       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11443         action = 2;
11444       else if (unformat (i, "action %d", &action))
11445         ;
11446       else if (unformat (i, "metadata %d", &metadata))
11447         ;
11448       else
11449         break;
11450     }
11451
11452   if (table_index == ~0)
11453     {
11454       errmsg ("Table index required");
11455       return -99;
11456     }
11457
11458   if (is_add && match == 0)
11459     {
11460       errmsg ("Match value required");
11461       return -99;
11462     }
11463
11464   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11465
11466   mp->is_add = is_add;
11467   mp->table_index = ntohl (table_index);
11468   mp->hit_next_index = ntohl (hit_next_index);
11469   mp->opaque_index = ntohl (opaque_index);
11470   mp->advance = ntohl (advance);
11471   mp->action = action;
11472   mp->metadata = ntohl (metadata);
11473   clib_memcpy (mp->match, match, vec_len (match));
11474   vec_free (match);
11475
11476   S (mp);
11477   W (ret);
11478   return ret;
11479 }
11480
11481 static int
11482 api_classify_set_interface_ip_table (vat_main_t * vam)
11483 {
11484   unformat_input_t *i = vam->input;
11485   vl_api_classify_set_interface_ip_table_t *mp;
11486   u32 sw_if_index;
11487   int sw_if_index_set;
11488   u32 table_index = ~0;
11489   u8 is_ipv6 = 0;
11490   int ret;
11491
11492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11493     {
11494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11495         sw_if_index_set = 1;
11496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11497         sw_if_index_set = 1;
11498       else if (unformat (i, "table %d", &table_index))
11499         ;
11500       else
11501         {
11502           clib_warning ("parse error '%U'", format_unformat_error, i);
11503           return -99;
11504         }
11505     }
11506
11507   if (sw_if_index_set == 0)
11508     {
11509       errmsg ("missing interface name or sw_if_index");
11510       return -99;
11511     }
11512
11513
11514   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11515
11516   mp->sw_if_index = ntohl (sw_if_index);
11517   mp->table_index = ntohl (table_index);
11518   mp->is_ipv6 = is_ipv6;
11519
11520   S (mp);
11521   W (ret);
11522   return ret;
11523 }
11524
11525 static int
11526 api_classify_set_interface_l2_tables (vat_main_t * vam)
11527 {
11528   unformat_input_t *i = vam->input;
11529   vl_api_classify_set_interface_l2_tables_t *mp;
11530   u32 sw_if_index;
11531   int sw_if_index_set;
11532   u32 ip4_table_index = ~0;
11533   u32 ip6_table_index = ~0;
11534   u32 other_table_index = ~0;
11535   u32 is_input = 1;
11536   int ret;
11537
11538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11539     {
11540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11541         sw_if_index_set = 1;
11542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11543         sw_if_index_set = 1;
11544       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11545         ;
11546       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11547         ;
11548       else if (unformat (i, "other-table %d", &other_table_index))
11549         ;
11550       else if (unformat (i, "is-input %d", &is_input))
11551         ;
11552       else
11553         {
11554           clib_warning ("parse error '%U'", format_unformat_error, i);
11555           return -99;
11556         }
11557     }
11558
11559   if (sw_if_index_set == 0)
11560     {
11561       errmsg ("missing interface name or sw_if_index");
11562       return -99;
11563     }
11564
11565
11566   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11567
11568   mp->sw_if_index = ntohl (sw_if_index);
11569   mp->ip4_table_index = ntohl (ip4_table_index);
11570   mp->ip6_table_index = ntohl (ip6_table_index);
11571   mp->other_table_index = ntohl (other_table_index);
11572   mp->is_input = (u8) is_input;
11573
11574   S (mp);
11575   W (ret);
11576   return ret;
11577 }
11578
11579 static int
11580 api_set_ipfix_exporter (vat_main_t * vam)
11581 {
11582   unformat_input_t *i = vam->input;
11583   vl_api_set_ipfix_exporter_t *mp;
11584   ip4_address_t collector_address;
11585   u8 collector_address_set = 0;
11586   u32 collector_port = ~0;
11587   ip4_address_t src_address;
11588   u8 src_address_set = 0;
11589   u32 vrf_id = ~0;
11590   u32 path_mtu = ~0;
11591   u32 template_interval = ~0;
11592   u8 udp_checksum = 0;
11593   int ret;
11594
11595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11596     {
11597       if (unformat (i, "collector_address %U", unformat_ip4_address,
11598                     &collector_address))
11599         collector_address_set = 1;
11600       else if (unformat (i, "collector_port %d", &collector_port))
11601         ;
11602       else if (unformat (i, "src_address %U", unformat_ip4_address,
11603                          &src_address))
11604         src_address_set = 1;
11605       else if (unformat (i, "vrf_id %d", &vrf_id))
11606         ;
11607       else if (unformat (i, "path_mtu %d", &path_mtu))
11608         ;
11609       else if (unformat (i, "template_interval %d", &template_interval))
11610         ;
11611       else if (unformat (i, "udp_checksum"))
11612         udp_checksum = 1;
11613       else
11614         break;
11615     }
11616
11617   if (collector_address_set == 0)
11618     {
11619       errmsg ("collector_address required");
11620       return -99;
11621     }
11622
11623   if (src_address_set == 0)
11624     {
11625       errmsg ("src_address required");
11626       return -99;
11627     }
11628
11629   M (SET_IPFIX_EXPORTER, mp);
11630
11631   memcpy (mp->collector_address, collector_address.data,
11632           sizeof (collector_address.data));
11633   mp->collector_port = htons ((u16) collector_port);
11634   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11635   mp->vrf_id = htonl (vrf_id);
11636   mp->path_mtu = htonl (path_mtu);
11637   mp->template_interval = htonl (template_interval);
11638   mp->udp_checksum = udp_checksum;
11639
11640   S (mp);
11641   W (ret);
11642   return ret;
11643 }
11644
11645 static int
11646 api_set_ipfix_classify_stream (vat_main_t * vam)
11647 {
11648   unformat_input_t *i = vam->input;
11649   vl_api_set_ipfix_classify_stream_t *mp;
11650   u32 domain_id = 0;
11651   u32 src_port = UDP_DST_PORT_ipfix;
11652   int ret;
11653
11654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11655     {
11656       if (unformat (i, "domain %d", &domain_id))
11657         ;
11658       else if (unformat (i, "src_port %d", &src_port))
11659         ;
11660       else
11661         {
11662           errmsg ("unknown input `%U'", format_unformat_error, i);
11663           return -99;
11664         }
11665     }
11666
11667   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11668
11669   mp->domain_id = htonl (domain_id);
11670   mp->src_port = htons ((u16) src_port);
11671
11672   S (mp);
11673   W (ret);
11674   return ret;
11675 }
11676
11677 static int
11678 api_ipfix_classify_table_add_del (vat_main_t * vam)
11679 {
11680   unformat_input_t *i = vam->input;
11681   vl_api_ipfix_classify_table_add_del_t *mp;
11682   int is_add = -1;
11683   u32 classify_table_index = ~0;
11684   u8 ip_version = 0;
11685   u8 transport_protocol = 255;
11686   int ret;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "add"))
11691         is_add = 1;
11692       else if (unformat (i, "del"))
11693         is_add = 0;
11694       else if (unformat (i, "table %d", &classify_table_index))
11695         ;
11696       else if (unformat (i, "ip4"))
11697         ip_version = 4;
11698       else if (unformat (i, "ip6"))
11699         ip_version = 6;
11700       else if (unformat (i, "tcp"))
11701         transport_protocol = 6;
11702       else if (unformat (i, "udp"))
11703         transport_protocol = 17;
11704       else
11705         {
11706           errmsg ("unknown input `%U'", format_unformat_error, i);
11707           return -99;
11708         }
11709     }
11710
11711   if (is_add == -1)
11712     {
11713       errmsg ("expecting: add|del");
11714       return -99;
11715     }
11716   if (classify_table_index == ~0)
11717     {
11718       errmsg ("classifier table not specified");
11719       return -99;
11720     }
11721   if (ip_version == 0)
11722     {
11723       errmsg ("IP version not specified");
11724       return -99;
11725     }
11726
11727   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11728
11729   mp->is_add = is_add;
11730   mp->table_id = htonl (classify_table_index);
11731   mp->ip_version = ip_version;
11732   mp->transport_protocol = transport_protocol;
11733
11734   S (mp);
11735   W (ret);
11736   return ret;
11737 }
11738
11739 static int
11740 api_get_node_index (vat_main_t * vam)
11741 {
11742   unformat_input_t *i = vam->input;
11743   vl_api_get_node_index_t *mp;
11744   u8 *name = 0;
11745   int ret;
11746
11747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11748     {
11749       if (unformat (i, "node %s", &name))
11750         ;
11751       else
11752         break;
11753     }
11754   if (name == 0)
11755     {
11756       errmsg ("node name required");
11757       return -99;
11758     }
11759   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11760     {
11761       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11762       return -99;
11763     }
11764
11765   M (GET_NODE_INDEX, mp);
11766   clib_memcpy (mp->node_name, name, vec_len (name));
11767   vec_free (name);
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static int
11775 api_get_next_index (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_get_next_index_t *mp;
11779   u8 *node_name = 0, *next_node_name = 0;
11780   int ret;
11781
11782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11783     {
11784       if (unformat (i, "node-name %s", &node_name))
11785         ;
11786       else if (unformat (i, "next-node-name %s", &next_node_name))
11787         break;
11788     }
11789
11790   if (node_name == 0)
11791     {
11792       errmsg ("node name required");
11793       return -99;
11794     }
11795   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11796     {
11797       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11798       return -99;
11799     }
11800
11801   if (next_node_name == 0)
11802     {
11803       errmsg ("next node name required");
11804       return -99;
11805     }
11806   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11807     {
11808       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11809       return -99;
11810     }
11811
11812   M (GET_NEXT_INDEX, mp);
11813   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11814   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11815   vec_free (node_name);
11816   vec_free (next_node_name);
11817
11818   S (mp);
11819   W (ret);
11820   return ret;
11821 }
11822
11823 static int
11824 api_add_node_next (vat_main_t * vam)
11825 {
11826   unformat_input_t *i = vam->input;
11827   vl_api_add_node_next_t *mp;
11828   u8 *name = 0;
11829   u8 *next = 0;
11830   int ret;
11831
11832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11833     {
11834       if (unformat (i, "node %s", &name))
11835         ;
11836       else if (unformat (i, "next %s", &next))
11837         ;
11838       else
11839         break;
11840     }
11841   if (name == 0)
11842     {
11843       errmsg ("node name required");
11844       return -99;
11845     }
11846   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11847     {
11848       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11849       return -99;
11850     }
11851   if (next == 0)
11852     {
11853       errmsg ("next node required");
11854       return -99;
11855     }
11856   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11857     {
11858       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11859       return -99;
11860     }
11861
11862   M (ADD_NODE_NEXT, mp);
11863   clib_memcpy (mp->node_name, name, vec_len (name));
11864   clib_memcpy (mp->next_name, next, vec_len (next));
11865   vec_free (name);
11866   vec_free (next);
11867
11868   S (mp);
11869   W (ret);
11870   return ret;
11871 }
11872
11873 static int
11874 api_l2tpv3_create_tunnel (vat_main_t * vam)
11875 {
11876   unformat_input_t *i = vam->input;
11877   ip6_address_t client_address, our_address;
11878   int client_address_set = 0;
11879   int our_address_set = 0;
11880   u32 local_session_id = 0;
11881   u32 remote_session_id = 0;
11882   u64 local_cookie = 0;
11883   u64 remote_cookie = 0;
11884   u8 l2_sublayer_present = 0;
11885   vl_api_l2tpv3_create_tunnel_t *mp;
11886   int ret;
11887
11888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11889     {
11890       if (unformat (i, "client_address %U", unformat_ip6_address,
11891                     &client_address))
11892         client_address_set = 1;
11893       else if (unformat (i, "our_address %U", unformat_ip6_address,
11894                          &our_address))
11895         our_address_set = 1;
11896       else if (unformat (i, "local_session_id %d", &local_session_id))
11897         ;
11898       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11899         ;
11900       else if (unformat (i, "local_cookie %lld", &local_cookie))
11901         ;
11902       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11903         ;
11904       else if (unformat (i, "l2-sublayer-present"))
11905         l2_sublayer_present = 1;
11906       else
11907         break;
11908     }
11909
11910   if (client_address_set == 0)
11911     {
11912       errmsg ("client_address required");
11913       return -99;
11914     }
11915
11916   if (our_address_set == 0)
11917     {
11918       errmsg ("our_address required");
11919       return -99;
11920     }
11921
11922   M (L2TPV3_CREATE_TUNNEL, mp);
11923
11924   clib_memcpy (mp->client_address, client_address.as_u8,
11925                sizeof (mp->client_address));
11926
11927   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11928
11929   mp->local_session_id = ntohl (local_session_id);
11930   mp->remote_session_id = ntohl (remote_session_id);
11931   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11932   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11933   mp->l2_sublayer_present = l2_sublayer_present;
11934   mp->is_ipv6 = 1;
11935
11936   S (mp);
11937   W (ret);
11938   return ret;
11939 }
11940
11941 static int
11942 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11943 {
11944   unformat_input_t *i = vam->input;
11945   u32 sw_if_index;
11946   u8 sw_if_index_set = 0;
11947   u64 new_local_cookie = 0;
11948   u64 new_remote_cookie = 0;
11949   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11950   int ret;
11951
11952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11953     {
11954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11955         sw_if_index_set = 1;
11956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11957         sw_if_index_set = 1;
11958       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11959         ;
11960       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11961         ;
11962       else
11963         break;
11964     }
11965
11966   if (sw_if_index_set == 0)
11967     {
11968       errmsg ("missing interface name or sw_if_index");
11969       return -99;
11970     }
11971
11972   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11973
11974   mp->sw_if_index = ntohl (sw_if_index);
11975   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11976   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11977
11978   S (mp);
11979   W (ret);
11980   return ret;
11981 }
11982
11983 static int
11984 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11985 {
11986   unformat_input_t *i = vam->input;
11987   vl_api_l2tpv3_interface_enable_disable_t *mp;
11988   u32 sw_if_index;
11989   u8 sw_if_index_set = 0;
11990   u8 enable_disable = 1;
11991   int ret;
11992
11993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11994     {
11995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11996         sw_if_index_set = 1;
11997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11998         sw_if_index_set = 1;
11999       else if (unformat (i, "enable"))
12000         enable_disable = 1;
12001       else if (unformat (i, "disable"))
12002         enable_disable = 0;
12003       else
12004         break;
12005     }
12006
12007   if (sw_if_index_set == 0)
12008     {
12009       errmsg ("missing interface name or sw_if_index");
12010       return -99;
12011     }
12012
12013   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12014
12015   mp->sw_if_index = ntohl (sw_if_index);
12016   mp->enable_disable = enable_disable;
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static int
12024 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12025 {
12026   unformat_input_t *i = vam->input;
12027   vl_api_l2tpv3_set_lookup_key_t *mp;
12028   u8 key = ~0;
12029   int ret;
12030
12031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (i, "lookup_v6_src"))
12034         key = L2T_LOOKUP_SRC_ADDRESS;
12035       else if (unformat (i, "lookup_v6_dst"))
12036         key = L2T_LOOKUP_DST_ADDRESS;
12037       else if (unformat (i, "lookup_session_id"))
12038         key = L2T_LOOKUP_SESSION_ID;
12039       else
12040         break;
12041     }
12042
12043   if (key == (u8) ~ 0)
12044     {
12045       errmsg ("l2tp session lookup key unset");
12046       return -99;
12047     }
12048
12049   M (L2TPV3_SET_LOOKUP_KEY, mp);
12050
12051   mp->key = key;
12052
12053   S (mp);
12054   W (ret);
12055   return ret;
12056 }
12057
12058 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12059   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12060 {
12061   vat_main_t *vam = &vat_main;
12062
12063   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12064          format_ip6_address, mp->our_address,
12065          format_ip6_address, mp->client_address,
12066          clib_net_to_host_u32 (mp->sw_if_index));
12067
12068   print (vam->ofp,
12069          "   local cookies %016llx %016llx remote cookie %016llx",
12070          clib_net_to_host_u64 (mp->local_cookie[0]),
12071          clib_net_to_host_u64 (mp->local_cookie[1]),
12072          clib_net_to_host_u64 (mp->remote_cookie));
12073
12074   print (vam->ofp, "   local session-id %d remote session-id %d",
12075          clib_net_to_host_u32 (mp->local_session_id),
12076          clib_net_to_host_u32 (mp->remote_session_id));
12077
12078   print (vam->ofp, "   l2 specific sublayer %s\n",
12079          mp->l2_sublayer_present ? "preset" : "absent");
12080
12081 }
12082
12083 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12084   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12085 {
12086   vat_main_t *vam = &vat_main;
12087   vat_json_node_t *node = NULL;
12088   struct in6_addr addr;
12089
12090   if (VAT_JSON_ARRAY != vam->json_tree.type)
12091     {
12092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12093       vat_json_init_array (&vam->json_tree);
12094     }
12095   node = vat_json_array_add (&vam->json_tree);
12096
12097   vat_json_init_object (node);
12098
12099   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12100   vat_json_object_add_ip6 (node, "our_address", addr);
12101   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12102   vat_json_object_add_ip6 (node, "client_address", addr);
12103
12104   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12105   vat_json_init_array (lc);
12106   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12107   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12108   vat_json_object_add_uint (node, "remote_cookie",
12109                             clib_net_to_host_u64 (mp->remote_cookie));
12110
12111   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12112   vat_json_object_add_uint (node, "local_session_id",
12113                             clib_net_to_host_u32 (mp->local_session_id));
12114   vat_json_object_add_uint (node, "remote_session_id",
12115                             clib_net_to_host_u32 (mp->remote_session_id));
12116   vat_json_object_add_string_copy (node, "l2_sublayer",
12117                                    mp->l2_sublayer_present ? (u8 *) "present"
12118                                    : (u8 *) "absent");
12119 }
12120
12121 static int
12122 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12123 {
12124   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12125   vl_api_control_ping_t *mp_ping;
12126   int ret;
12127
12128   /* Get list of l2tpv3-tunnel interfaces */
12129   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12130   S (mp);
12131
12132   /* Use a control ping for synchronization */
12133   MPING (CONTROL_PING, mp_ping);
12134   S (mp_ping);
12135
12136   W (ret);
12137   return ret;
12138 }
12139
12140
12141 static void vl_api_sw_interface_tap_details_t_handler
12142   (vl_api_sw_interface_tap_details_t * mp)
12143 {
12144   vat_main_t *vam = &vat_main;
12145
12146   print (vam->ofp, "%-16s %d",
12147          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12148 }
12149
12150 static void vl_api_sw_interface_tap_details_t_handler_json
12151   (vl_api_sw_interface_tap_details_t * mp)
12152 {
12153   vat_main_t *vam = &vat_main;
12154   vat_json_node_t *node = NULL;
12155
12156   if (VAT_JSON_ARRAY != vam->json_tree.type)
12157     {
12158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12159       vat_json_init_array (&vam->json_tree);
12160     }
12161   node = vat_json_array_add (&vam->json_tree);
12162
12163   vat_json_init_object (node);
12164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12165   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12166 }
12167
12168 static int
12169 api_sw_interface_tap_dump (vat_main_t * vam)
12170 {
12171   vl_api_sw_interface_tap_dump_t *mp;
12172   vl_api_control_ping_t *mp_ping;
12173   int ret;
12174
12175   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12176   /* Get list of tap interfaces */
12177   M (SW_INTERFACE_TAP_DUMP, mp);
12178   S (mp);
12179
12180   /* Use a control ping for synchronization */
12181   MPING (CONTROL_PING, mp_ping);
12182   S (mp_ping);
12183
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static uword unformat_vxlan_decap_next
12189   (unformat_input_t * input, va_list * args)
12190 {
12191   u32 *result = va_arg (*args, u32 *);
12192   u32 tmp;
12193
12194   if (unformat (input, "l2"))
12195     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12196   else if (unformat (input, "%d", &tmp))
12197     *result = tmp;
12198   else
12199     return 0;
12200   return 1;
12201 }
12202
12203 static int
12204 api_vxlan_add_del_tunnel (vat_main_t * vam)
12205 {
12206   unformat_input_t *line_input = vam->input;
12207   vl_api_vxlan_add_del_tunnel_t *mp;
12208   ip46_address_t src, dst;
12209   u8 is_add = 1;
12210   u8 ipv4_set = 0, ipv6_set = 0;
12211   u8 src_set = 0;
12212   u8 dst_set = 0;
12213   u8 grp_set = 0;
12214   u32 mcast_sw_if_index = ~0;
12215   u32 encap_vrf_id = 0;
12216   u32 decap_next_index = ~0;
12217   u32 vni = 0;
12218   int ret;
12219
12220   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12221   memset (&src, 0, sizeof src);
12222   memset (&dst, 0, sizeof dst);
12223
12224   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12225     {
12226       if (unformat (line_input, "del"))
12227         is_add = 0;
12228       else
12229         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12230         {
12231           ipv4_set = 1;
12232           src_set = 1;
12233         }
12234       else
12235         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12236         {
12237           ipv4_set = 1;
12238           dst_set = 1;
12239         }
12240       else
12241         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12242         {
12243           ipv6_set = 1;
12244           src_set = 1;
12245         }
12246       else
12247         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12248         {
12249           ipv6_set = 1;
12250           dst_set = 1;
12251         }
12252       else if (unformat (line_input, "group %U %U",
12253                          unformat_ip4_address, &dst.ip4,
12254                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12255         {
12256           grp_set = dst_set = 1;
12257           ipv4_set = 1;
12258         }
12259       else if (unformat (line_input, "group %U",
12260                          unformat_ip4_address, &dst.ip4))
12261         {
12262           grp_set = dst_set = 1;
12263           ipv4_set = 1;
12264         }
12265       else if (unformat (line_input, "group %U %U",
12266                          unformat_ip6_address, &dst.ip6,
12267                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12268         {
12269           grp_set = dst_set = 1;
12270           ipv6_set = 1;
12271         }
12272       else if (unformat (line_input, "group %U",
12273                          unformat_ip6_address, &dst.ip6))
12274         {
12275           grp_set = dst_set = 1;
12276           ipv6_set = 1;
12277         }
12278       else
12279         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12280         ;
12281       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12282         ;
12283       else if (unformat (line_input, "decap-next %U",
12284                          unformat_vxlan_decap_next, &decap_next_index))
12285         ;
12286       else if (unformat (line_input, "vni %d", &vni))
12287         ;
12288       else
12289         {
12290           errmsg ("parse error '%U'", format_unformat_error, line_input);
12291           return -99;
12292         }
12293     }
12294
12295   if (src_set == 0)
12296     {
12297       errmsg ("tunnel src address not specified");
12298       return -99;
12299     }
12300   if (dst_set == 0)
12301     {
12302       errmsg ("tunnel dst address not specified");
12303       return -99;
12304     }
12305
12306   if (grp_set && !ip46_address_is_multicast (&dst))
12307     {
12308       errmsg ("tunnel group address not multicast");
12309       return -99;
12310     }
12311   if (grp_set && mcast_sw_if_index == ~0)
12312     {
12313       errmsg ("tunnel nonexistent multicast device");
12314       return -99;
12315     }
12316   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12317     {
12318       errmsg ("tunnel dst address must be unicast");
12319       return -99;
12320     }
12321
12322
12323   if (ipv4_set && ipv6_set)
12324     {
12325       errmsg ("both IPv4 and IPv6 addresses specified");
12326       return -99;
12327     }
12328
12329   if ((vni == 0) || (vni >> 24))
12330     {
12331       errmsg ("vni not specified or out of range");
12332       return -99;
12333     }
12334
12335   M (VXLAN_ADD_DEL_TUNNEL, mp);
12336
12337   if (ipv6_set)
12338     {
12339       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12340       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12341     }
12342   else
12343     {
12344       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12345       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12346     }
12347   mp->encap_vrf_id = ntohl (encap_vrf_id);
12348   mp->decap_next_index = ntohl (decap_next_index);
12349   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12350   mp->vni = ntohl (vni);
12351   mp->is_add = is_add;
12352   mp->is_ipv6 = ipv6_set;
12353
12354   S (mp);
12355   W (ret);
12356   return ret;
12357 }
12358
12359 static void vl_api_vxlan_tunnel_details_t_handler
12360   (vl_api_vxlan_tunnel_details_t * mp)
12361 {
12362   vat_main_t *vam = &vat_main;
12363   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12364   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12365
12366   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12367          ntohl (mp->sw_if_index),
12368          format_ip46_address, &src, IP46_TYPE_ANY,
12369          format_ip46_address, &dst, IP46_TYPE_ANY,
12370          ntohl (mp->encap_vrf_id),
12371          ntohl (mp->decap_next_index), ntohl (mp->vni),
12372          ntohl (mp->mcast_sw_if_index));
12373 }
12374
12375 static void vl_api_vxlan_tunnel_details_t_handler_json
12376   (vl_api_vxlan_tunnel_details_t * mp)
12377 {
12378   vat_main_t *vam = &vat_main;
12379   vat_json_node_t *node = NULL;
12380
12381   if (VAT_JSON_ARRAY != vam->json_tree.type)
12382     {
12383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12384       vat_json_init_array (&vam->json_tree);
12385     }
12386   node = vat_json_array_add (&vam->json_tree);
12387
12388   vat_json_init_object (node);
12389   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12390   if (mp->is_ipv6)
12391     {
12392       struct in6_addr ip6;
12393
12394       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12395       vat_json_object_add_ip6 (node, "src_address", ip6);
12396       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12397       vat_json_object_add_ip6 (node, "dst_address", ip6);
12398     }
12399   else
12400     {
12401       struct in_addr ip4;
12402
12403       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12404       vat_json_object_add_ip4 (node, "src_address", ip4);
12405       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12406       vat_json_object_add_ip4 (node, "dst_address", ip4);
12407     }
12408   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12409   vat_json_object_add_uint (node, "decap_next_index",
12410                             ntohl (mp->decap_next_index));
12411   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12412   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12413   vat_json_object_add_uint (node, "mcast_sw_if_index",
12414                             ntohl (mp->mcast_sw_if_index));
12415 }
12416
12417 static int
12418 api_vxlan_tunnel_dump (vat_main_t * vam)
12419 {
12420   unformat_input_t *i = vam->input;
12421   vl_api_vxlan_tunnel_dump_t *mp;
12422   vl_api_control_ping_t *mp_ping;
12423   u32 sw_if_index;
12424   u8 sw_if_index_set = 0;
12425   int ret;
12426
12427   /* Parse args required to build the message */
12428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12429     {
12430       if (unformat (i, "sw_if_index %d", &sw_if_index))
12431         sw_if_index_set = 1;
12432       else
12433         break;
12434     }
12435
12436   if (sw_if_index_set == 0)
12437     {
12438       sw_if_index = ~0;
12439     }
12440
12441   if (!vam->json_output)
12442     {
12443       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12444              "sw_if_index", "src_address", "dst_address",
12445              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12446     }
12447
12448   /* Get list of vxlan-tunnel interfaces */
12449   M (VXLAN_TUNNEL_DUMP, mp);
12450
12451   mp->sw_if_index = htonl (sw_if_index);
12452
12453   S (mp);
12454
12455   /* Use a control ping for synchronization */
12456   MPING (CONTROL_PING, mp_ping);
12457   S (mp_ping);
12458
12459   W (ret);
12460   return ret;
12461 }
12462
12463 static uword unformat_geneve_decap_next
12464   (unformat_input_t * input, va_list * args)
12465 {
12466   u32 *result = va_arg (*args, u32 *);
12467   u32 tmp;
12468
12469   if (unformat (input, "l2"))
12470     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12471   else if (unformat (input, "%d", &tmp))
12472     *result = tmp;
12473   else
12474     return 0;
12475   return 1;
12476 }
12477
12478 static int
12479 api_geneve_add_del_tunnel (vat_main_t * vam)
12480 {
12481   unformat_input_t *line_input = vam->input;
12482   vl_api_geneve_add_del_tunnel_t *mp;
12483   ip46_address_t src, dst;
12484   u8 is_add = 1;
12485   u8 ipv4_set = 0, ipv6_set = 0;
12486   u8 src_set = 0;
12487   u8 dst_set = 0;
12488   u8 grp_set = 0;
12489   u32 mcast_sw_if_index = ~0;
12490   u32 encap_vrf_id = 0;
12491   u32 decap_next_index = ~0;
12492   u32 vni = 0;
12493   int ret;
12494
12495   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12496   memset (&src, 0, sizeof src);
12497   memset (&dst, 0, sizeof dst);
12498
12499   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12500     {
12501       if (unformat (line_input, "del"))
12502         is_add = 0;
12503       else
12504         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12505         {
12506           ipv4_set = 1;
12507           src_set = 1;
12508         }
12509       else
12510         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12511         {
12512           ipv4_set = 1;
12513           dst_set = 1;
12514         }
12515       else
12516         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12517         {
12518           ipv6_set = 1;
12519           src_set = 1;
12520         }
12521       else
12522         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12523         {
12524           ipv6_set = 1;
12525           dst_set = 1;
12526         }
12527       else if (unformat (line_input, "group %U %U",
12528                          unformat_ip4_address, &dst.ip4,
12529                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12530         {
12531           grp_set = dst_set = 1;
12532           ipv4_set = 1;
12533         }
12534       else if (unformat (line_input, "group %U",
12535                          unformat_ip4_address, &dst.ip4))
12536         {
12537           grp_set = dst_set = 1;
12538           ipv4_set = 1;
12539         }
12540       else if (unformat (line_input, "group %U %U",
12541                          unformat_ip6_address, &dst.ip6,
12542                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12543         {
12544           grp_set = dst_set = 1;
12545           ipv6_set = 1;
12546         }
12547       else if (unformat (line_input, "group %U",
12548                          unformat_ip6_address, &dst.ip6))
12549         {
12550           grp_set = dst_set = 1;
12551           ipv6_set = 1;
12552         }
12553       else
12554         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12555         ;
12556       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12557         ;
12558       else if (unformat (line_input, "decap-next %U",
12559                          unformat_geneve_decap_next, &decap_next_index))
12560         ;
12561       else if (unformat (line_input, "vni %d", &vni))
12562         ;
12563       else
12564         {
12565           errmsg ("parse error '%U'", format_unformat_error, line_input);
12566           return -99;
12567         }
12568     }
12569
12570   if (src_set == 0)
12571     {
12572       errmsg ("tunnel src address not specified");
12573       return -99;
12574     }
12575   if (dst_set == 0)
12576     {
12577       errmsg ("tunnel dst address not specified");
12578       return -99;
12579     }
12580
12581   if (grp_set && !ip46_address_is_multicast (&dst))
12582     {
12583       errmsg ("tunnel group address not multicast");
12584       return -99;
12585     }
12586   if (grp_set && mcast_sw_if_index == ~0)
12587     {
12588       errmsg ("tunnel nonexistent multicast device");
12589       return -99;
12590     }
12591   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12592     {
12593       errmsg ("tunnel dst address must be unicast");
12594       return -99;
12595     }
12596
12597
12598   if (ipv4_set && ipv6_set)
12599     {
12600       errmsg ("both IPv4 and IPv6 addresses specified");
12601       return -99;
12602     }
12603
12604   if ((vni == 0) || (vni >> 24))
12605     {
12606       errmsg ("vni not specified or out of range");
12607       return -99;
12608     }
12609
12610   M (GENEVE_ADD_DEL_TUNNEL, mp);
12611
12612   if (ipv6_set)
12613     {
12614       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12615       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12616     }
12617   else
12618     {
12619       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12620       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12621     }
12622   mp->encap_vrf_id = ntohl (encap_vrf_id);
12623   mp->decap_next_index = ntohl (decap_next_index);
12624   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12625   mp->vni = ntohl (vni);
12626   mp->is_add = is_add;
12627   mp->is_ipv6 = ipv6_set;
12628
12629   S (mp);
12630   W (ret);
12631   return ret;
12632 }
12633
12634 static void vl_api_geneve_tunnel_details_t_handler
12635   (vl_api_geneve_tunnel_details_t * mp)
12636 {
12637   vat_main_t *vam = &vat_main;
12638   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12639   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12640
12641   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12642          ntohl (mp->sw_if_index),
12643          format_ip46_address, &src, IP46_TYPE_ANY,
12644          format_ip46_address, &dst, IP46_TYPE_ANY,
12645          ntohl (mp->encap_vrf_id),
12646          ntohl (mp->decap_next_index), ntohl (mp->vni),
12647          ntohl (mp->mcast_sw_if_index));
12648 }
12649
12650 static void vl_api_geneve_tunnel_details_t_handler_json
12651   (vl_api_geneve_tunnel_details_t * mp)
12652 {
12653   vat_main_t *vam = &vat_main;
12654   vat_json_node_t *node = NULL;
12655
12656   if (VAT_JSON_ARRAY != vam->json_tree.type)
12657     {
12658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12659       vat_json_init_array (&vam->json_tree);
12660     }
12661   node = vat_json_array_add (&vam->json_tree);
12662
12663   vat_json_init_object (node);
12664   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12665   if (mp->is_ipv6)
12666     {
12667       struct in6_addr ip6;
12668
12669       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12670       vat_json_object_add_ip6 (node, "src_address", ip6);
12671       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12672       vat_json_object_add_ip6 (node, "dst_address", ip6);
12673     }
12674   else
12675     {
12676       struct in_addr ip4;
12677
12678       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12679       vat_json_object_add_ip4 (node, "src_address", ip4);
12680       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12681       vat_json_object_add_ip4 (node, "dst_address", ip4);
12682     }
12683   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12684   vat_json_object_add_uint (node, "decap_next_index",
12685                             ntohl (mp->decap_next_index));
12686   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12687   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12688   vat_json_object_add_uint (node, "mcast_sw_if_index",
12689                             ntohl (mp->mcast_sw_if_index));
12690 }
12691
12692 static int
12693 api_geneve_tunnel_dump (vat_main_t * vam)
12694 {
12695   unformat_input_t *i = vam->input;
12696   vl_api_geneve_tunnel_dump_t *mp;
12697   vl_api_control_ping_t *mp_ping;
12698   u32 sw_if_index;
12699   u8 sw_if_index_set = 0;
12700   int ret;
12701
12702   /* Parse args required to build the message */
12703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12704     {
12705       if (unformat (i, "sw_if_index %d", &sw_if_index))
12706         sw_if_index_set = 1;
12707       else
12708         break;
12709     }
12710
12711   if (sw_if_index_set == 0)
12712     {
12713       sw_if_index = ~0;
12714     }
12715
12716   if (!vam->json_output)
12717     {
12718       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12719              "sw_if_index", "local_address", "remote_address",
12720              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12721     }
12722
12723   /* Get list of geneve-tunnel interfaces */
12724   M (GENEVE_TUNNEL_DUMP, mp);
12725
12726   mp->sw_if_index = htonl (sw_if_index);
12727
12728   S (mp);
12729
12730   /* Use a control ping for synchronization */
12731   M (CONTROL_PING, mp_ping);
12732   S (mp_ping);
12733
12734   W (ret);
12735   return ret;
12736 }
12737
12738 static int
12739 api_gre_add_del_tunnel (vat_main_t * vam)
12740 {
12741   unformat_input_t *line_input = vam->input;
12742   vl_api_gre_add_del_tunnel_t *mp;
12743   ip4_address_t src4, dst4;
12744   ip6_address_t src6, dst6;
12745   u8 is_add = 1;
12746   u8 ipv4_set = 0;
12747   u8 ipv6_set = 0;
12748   u8 teb = 0;
12749   u8 src_set = 0;
12750   u8 dst_set = 0;
12751   u32 outer_fib_id = 0;
12752   int ret;
12753
12754   memset (&src4, 0, sizeof src4);
12755   memset (&dst4, 0, sizeof dst4);
12756   memset (&src6, 0, sizeof src6);
12757   memset (&dst6, 0, sizeof dst6);
12758
12759   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (line_input, "del"))
12762         is_add = 0;
12763       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12764         {
12765           src_set = 1;
12766           ipv4_set = 1;
12767         }
12768       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12769         {
12770           dst_set = 1;
12771           ipv4_set = 1;
12772         }
12773       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12774         {
12775           src_set = 1;
12776           ipv6_set = 1;
12777         }
12778       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12779         {
12780           dst_set = 1;
12781           ipv6_set = 1;
12782         }
12783       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12784         ;
12785       else if (unformat (line_input, "teb"))
12786         teb = 1;
12787       else
12788         {
12789           errmsg ("parse error '%U'", format_unformat_error, line_input);
12790           return -99;
12791         }
12792     }
12793
12794   if (src_set == 0)
12795     {
12796       errmsg ("tunnel src address not specified");
12797       return -99;
12798     }
12799   if (dst_set == 0)
12800     {
12801       errmsg ("tunnel dst address not specified");
12802       return -99;
12803     }
12804   if (ipv4_set && ipv6_set)
12805     {
12806       errmsg ("both IPv4 and IPv6 addresses specified");
12807       return -99;
12808     }
12809
12810
12811   M (GRE_ADD_DEL_TUNNEL, mp);
12812
12813   if (ipv4_set)
12814     {
12815       clib_memcpy (&mp->src_address, &src4, 4);
12816       clib_memcpy (&mp->dst_address, &dst4, 4);
12817     }
12818   else
12819     {
12820       clib_memcpy (&mp->src_address, &src6, 16);
12821       clib_memcpy (&mp->dst_address, &dst6, 16);
12822     }
12823   mp->outer_fib_id = ntohl (outer_fib_id);
12824   mp->is_add = is_add;
12825   mp->teb = teb;
12826   mp->is_ipv6 = ipv6_set;
12827
12828   S (mp);
12829   W (ret);
12830   return ret;
12831 }
12832
12833 static void vl_api_gre_tunnel_details_t_handler
12834   (vl_api_gre_tunnel_details_t * mp)
12835 {
12836   vat_main_t *vam = &vat_main;
12837   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12838   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12839
12840   print (vam->ofp, "%11d%24U%24U%6d%14d",
12841          ntohl (mp->sw_if_index),
12842          format_ip46_address, &src, IP46_TYPE_ANY,
12843          format_ip46_address, &dst, IP46_TYPE_ANY,
12844          mp->teb, ntohl (mp->outer_fib_id));
12845 }
12846
12847 static void vl_api_gre_tunnel_details_t_handler_json
12848   (vl_api_gre_tunnel_details_t * mp)
12849 {
12850   vat_main_t *vam = &vat_main;
12851   vat_json_node_t *node = NULL;
12852   struct in_addr ip4;
12853   struct in6_addr ip6;
12854
12855   if (VAT_JSON_ARRAY != vam->json_tree.type)
12856     {
12857       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12858       vat_json_init_array (&vam->json_tree);
12859     }
12860   node = vat_json_array_add (&vam->json_tree);
12861
12862   vat_json_init_object (node);
12863   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12864   if (!mp->is_ipv6)
12865     {
12866       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12867       vat_json_object_add_ip4 (node, "src_address", ip4);
12868       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12869       vat_json_object_add_ip4 (node, "dst_address", ip4);
12870     }
12871   else
12872     {
12873       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12874       vat_json_object_add_ip6 (node, "src_address", ip6);
12875       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12876       vat_json_object_add_ip6 (node, "dst_address", ip6);
12877     }
12878   vat_json_object_add_uint (node, "teb", mp->teb);
12879   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12880   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12881 }
12882
12883 static int
12884 api_gre_tunnel_dump (vat_main_t * vam)
12885 {
12886   unformat_input_t *i = vam->input;
12887   vl_api_gre_tunnel_dump_t *mp;
12888   vl_api_control_ping_t *mp_ping;
12889   u32 sw_if_index;
12890   u8 sw_if_index_set = 0;
12891   int ret;
12892
12893   /* Parse args required to build the message */
12894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (i, "sw_if_index %d", &sw_if_index))
12897         sw_if_index_set = 1;
12898       else
12899         break;
12900     }
12901
12902   if (sw_if_index_set == 0)
12903     {
12904       sw_if_index = ~0;
12905     }
12906
12907   if (!vam->json_output)
12908     {
12909       print (vam->ofp, "%11s%24s%24s%6s%14s",
12910              "sw_if_index", "src_address", "dst_address", "teb",
12911              "outer_fib_id");
12912     }
12913
12914   /* Get list of gre-tunnel interfaces */
12915   M (GRE_TUNNEL_DUMP, mp);
12916
12917   mp->sw_if_index = htonl (sw_if_index);
12918
12919   S (mp);
12920
12921   /* Use a control ping for synchronization */
12922   MPING (CONTROL_PING, mp_ping);
12923   S (mp_ping);
12924
12925   W (ret);
12926   return ret;
12927 }
12928
12929 static int
12930 api_l2_fib_clear_table (vat_main_t * vam)
12931 {
12932 //  unformat_input_t * i = vam->input;
12933   vl_api_l2_fib_clear_table_t *mp;
12934   int ret;
12935
12936   M (L2_FIB_CLEAR_TABLE, mp);
12937
12938   S (mp);
12939   W (ret);
12940   return ret;
12941 }
12942
12943 static int
12944 api_l2_interface_efp_filter (vat_main_t * vam)
12945 {
12946   unformat_input_t *i = vam->input;
12947   vl_api_l2_interface_efp_filter_t *mp;
12948   u32 sw_if_index;
12949   u8 enable = 1;
12950   u8 sw_if_index_set = 0;
12951   int ret;
12952
12953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12954     {
12955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12956         sw_if_index_set = 1;
12957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12958         sw_if_index_set = 1;
12959       else if (unformat (i, "enable"))
12960         enable = 1;
12961       else if (unformat (i, "disable"))
12962         enable = 0;
12963       else
12964         {
12965           clib_warning ("parse error '%U'", format_unformat_error, i);
12966           return -99;
12967         }
12968     }
12969
12970   if (sw_if_index_set == 0)
12971     {
12972       errmsg ("missing sw_if_index");
12973       return -99;
12974     }
12975
12976   M (L2_INTERFACE_EFP_FILTER, mp);
12977
12978   mp->sw_if_index = ntohl (sw_if_index);
12979   mp->enable_disable = enable;
12980
12981   S (mp);
12982   W (ret);
12983   return ret;
12984 }
12985
12986 #define foreach_vtr_op                          \
12987 _("disable",  L2_VTR_DISABLED)                  \
12988 _("push-1",  L2_VTR_PUSH_1)                     \
12989 _("push-2",  L2_VTR_PUSH_2)                     \
12990 _("pop-1",  L2_VTR_POP_1)                       \
12991 _("pop-2",  L2_VTR_POP_2)                       \
12992 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12993 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12994 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12995 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12996
12997 static int
12998 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12999 {
13000   unformat_input_t *i = vam->input;
13001   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13002   u32 sw_if_index;
13003   u8 sw_if_index_set = 0;
13004   u8 vtr_op_set = 0;
13005   u32 vtr_op = 0;
13006   u32 push_dot1q = 1;
13007   u32 tag1 = ~0;
13008   u32 tag2 = ~0;
13009   int ret;
13010
13011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13014         sw_if_index_set = 1;
13015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13016         sw_if_index_set = 1;
13017       else if (unformat (i, "vtr_op %d", &vtr_op))
13018         vtr_op_set = 1;
13019 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13020       foreach_vtr_op
13021 #undef _
13022         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13023         ;
13024       else if (unformat (i, "tag1 %d", &tag1))
13025         ;
13026       else if (unformat (i, "tag2 %d", &tag2))
13027         ;
13028       else
13029         {
13030           clib_warning ("parse error '%U'", format_unformat_error, i);
13031           return -99;
13032         }
13033     }
13034
13035   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13036     {
13037       errmsg ("missing vtr operation or sw_if_index");
13038       return -99;
13039     }
13040
13041   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13042   mp->sw_if_index = ntohl (sw_if_index);
13043   mp->vtr_op = ntohl (vtr_op);
13044   mp->push_dot1q = ntohl (push_dot1q);
13045   mp->tag1 = ntohl (tag1);
13046   mp->tag2 = ntohl (tag2);
13047
13048   S (mp);
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_create_vhost_user_if (vat_main_t * vam)
13055 {
13056   unformat_input_t *i = vam->input;
13057   vl_api_create_vhost_user_if_t *mp;
13058   u8 *file_name;
13059   u8 is_server = 0;
13060   u8 file_name_set = 0;
13061   u32 custom_dev_instance = ~0;
13062   u8 hwaddr[6];
13063   u8 use_custom_mac = 0;
13064   u8 *tag = 0;
13065   int ret;
13066
13067   /* Shut up coverity */
13068   memset (hwaddr, 0, sizeof (hwaddr));
13069
13070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13071     {
13072       if (unformat (i, "socket %s", &file_name))
13073         {
13074           file_name_set = 1;
13075         }
13076       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13077         ;
13078       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13079         use_custom_mac = 1;
13080       else if (unformat (i, "server"))
13081         is_server = 1;
13082       else if (unformat (i, "tag %s", &tag))
13083         ;
13084       else
13085         break;
13086     }
13087
13088   if (file_name_set == 0)
13089     {
13090       errmsg ("missing socket file name");
13091       return -99;
13092     }
13093
13094   if (vec_len (file_name) > 255)
13095     {
13096       errmsg ("socket file name too long");
13097       return -99;
13098     }
13099   vec_add1 (file_name, 0);
13100
13101   M (CREATE_VHOST_USER_IF, mp);
13102
13103   mp->is_server = is_server;
13104   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13105   vec_free (file_name);
13106   if (custom_dev_instance != ~0)
13107     {
13108       mp->renumber = 1;
13109       mp->custom_dev_instance = ntohl (custom_dev_instance);
13110     }
13111   mp->use_custom_mac = use_custom_mac;
13112   clib_memcpy (mp->mac_address, hwaddr, 6);
13113   if (tag)
13114     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13115   vec_free (tag);
13116
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122 static int
13123 api_modify_vhost_user_if (vat_main_t * vam)
13124 {
13125   unformat_input_t *i = vam->input;
13126   vl_api_modify_vhost_user_if_t *mp;
13127   u8 *file_name;
13128   u8 is_server = 0;
13129   u8 file_name_set = 0;
13130   u32 custom_dev_instance = ~0;
13131   u8 sw_if_index_set = 0;
13132   u32 sw_if_index = (u32) ~ 0;
13133   int ret;
13134
13135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13136     {
13137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13138         sw_if_index_set = 1;
13139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13140         sw_if_index_set = 1;
13141       else if (unformat (i, "socket %s", &file_name))
13142         {
13143           file_name_set = 1;
13144         }
13145       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13146         ;
13147       else if (unformat (i, "server"))
13148         is_server = 1;
13149       else
13150         break;
13151     }
13152
13153   if (sw_if_index_set == 0)
13154     {
13155       errmsg ("missing sw_if_index or interface name");
13156       return -99;
13157     }
13158
13159   if (file_name_set == 0)
13160     {
13161       errmsg ("missing socket file name");
13162       return -99;
13163     }
13164
13165   if (vec_len (file_name) > 255)
13166     {
13167       errmsg ("socket file name too long");
13168       return -99;
13169     }
13170   vec_add1 (file_name, 0);
13171
13172   M (MODIFY_VHOST_USER_IF, mp);
13173
13174   mp->sw_if_index = ntohl (sw_if_index);
13175   mp->is_server = is_server;
13176   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13177   vec_free (file_name);
13178   if (custom_dev_instance != ~0)
13179     {
13180       mp->renumber = 1;
13181       mp->custom_dev_instance = ntohl (custom_dev_instance);
13182     }
13183
13184   S (mp);
13185   W (ret);
13186   return ret;
13187 }
13188
13189 static int
13190 api_delete_vhost_user_if (vat_main_t * vam)
13191 {
13192   unformat_input_t *i = vam->input;
13193   vl_api_delete_vhost_user_if_t *mp;
13194   u32 sw_if_index = ~0;
13195   u8 sw_if_index_set = 0;
13196   int ret;
13197
13198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13199     {
13200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13201         sw_if_index_set = 1;
13202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13203         sw_if_index_set = 1;
13204       else
13205         break;
13206     }
13207
13208   if (sw_if_index_set == 0)
13209     {
13210       errmsg ("missing sw_if_index or interface name");
13211       return -99;
13212     }
13213
13214
13215   M (DELETE_VHOST_USER_IF, mp);
13216
13217   mp->sw_if_index = ntohl (sw_if_index);
13218
13219   S (mp);
13220   W (ret);
13221   return ret;
13222 }
13223
13224 static void vl_api_sw_interface_vhost_user_details_t_handler
13225   (vl_api_sw_interface_vhost_user_details_t * mp)
13226 {
13227   vat_main_t *vam = &vat_main;
13228
13229   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13230          (char *) mp->interface_name,
13231          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13232          clib_net_to_host_u64 (mp->features), mp->is_server,
13233          ntohl (mp->num_regions), (char *) mp->sock_filename);
13234   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13235 }
13236
13237 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13238   (vl_api_sw_interface_vhost_user_details_t * mp)
13239 {
13240   vat_main_t *vam = &vat_main;
13241   vat_json_node_t *node = NULL;
13242
13243   if (VAT_JSON_ARRAY != vam->json_tree.type)
13244     {
13245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13246       vat_json_init_array (&vam->json_tree);
13247     }
13248   node = vat_json_array_add (&vam->json_tree);
13249
13250   vat_json_init_object (node);
13251   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13252   vat_json_object_add_string_copy (node, "interface_name",
13253                                    mp->interface_name);
13254   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13255                             ntohl (mp->virtio_net_hdr_sz));
13256   vat_json_object_add_uint (node, "features",
13257                             clib_net_to_host_u64 (mp->features));
13258   vat_json_object_add_uint (node, "is_server", mp->is_server);
13259   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13260   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13261   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13262 }
13263
13264 static int
13265 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13266 {
13267   vl_api_sw_interface_vhost_user_dump_t *mp;
13268   vl_api_control_ping_t *mp_ping;
13269   int ret;
13270   print (vam->ofp,
13271          "Interface name            idx hdr_sz features server regions filename");
13272
13273   /* Get list of vhost-user interfaces */
13274   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13275   S (mp);
13276
13277   /* Use a control ping for synchronization */
13278   MPING (CONTROL_PING, mp_ping);
13279   S (mp_ping);
13280
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static int
13286 api_show_version (vat_main_t * vam)
13287 {
13288   vl_api_show_version_t *mp;
13289   int ret;
13290
13291   M (SHOW_VERSION, mp);
13292
13293   S (mp);
13294   W (ret);
13295   return ret;
13296 }
13297
13298
13299 static int
13300 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13301 {
13302   unformat_input_t *line_input = vam->input;
13303   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13304   ip4_address_t local4, remote4;
13305   ip6_address_t local6, remote6;
13306   u8 is_add = 1;
13307   u8 ipv4_set = 0, ipv6_set = 0;
13308   u8 local_set = 0;
13309   u8 remote_set = 0;
13310   u8 grp_set = 0;
13311   u32 mcast_sw_if_index = ~0;
13312   u32 encap_vrf_id = 0;
13313   u32 decap_vrf_id = 0;
13314   u8 protocol = ~0;
13315   u32 vni;
13316   u8 vni_set = 0;
13317   int ret;
13318
13319   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13320   memset (&local4, 0, sizeof local4);
13321   memset (&remote4, 0, sizeof remote4);
13322   memset (&local6, 0, sizeof local6);
13323   memset (&remote6, 0, sizeof remote6);
13324
13325   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13326     {
13327       if (unformat (line_input, "del"))
13328         is_add = 0;
13329       else if (unformat (line_input, "local %U",
13330                          unformat_ip4_address, &local4))
13331         {
13332           local_set = 1;
13333           ipv4_set = 1;
13334         }
13335       else if (unformat (line_input, "remote %U",
13336                          unformat_ip4_address, &remote4))
13337         {
13338           remote_set = 1;
13339           ipv4_set = 1;
13340         }
13341       else if (unformat (line_input, "local %U",
13342                          unformat_ip6_address, &local6))
13343         {
13344           local_set = 1;
13345           ipv6_set = 1;
13346         }
13347       else if (unformat (line_input, "remote %U",
13348                          unformat_ip6_address, &remote6))
13349         {
13350           remote_set = 1;
13351           ipv6_set = 1;
13352         }
13353       else if (unformat (line_input, "group %U %U",
13354                          unformat_ip4_address, &remote4,
13355                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13356         {
13357           grp_set = remote_set = 1;
13358           ipv4_set = 1;
13359         }
13360       else if (unformat (line_input, "group %U",
13361                          unformat_ip4_address, &remote4))
13362         {
13363           grp_set = remote_set = 1;
13364           ipv4_set = 1;
13365         }
13366       else if (unformat (line_input, "group %U %U",
13367                          unformat_ip6_address, &remote6,
13368                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13369         {
13370           grp_set = remote_set = 1;
13371           ipv6_set = 1;
13372         }
13373       else if (unformat (line_input, "group %U",
13374                          unformat_ip6_address, &remote6))
13375         {
13376           grp_set = remote_set = 1;
13377           ipv6_set = 1;
13378         }
13379       else
13380         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13381         ;
13382       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13383         ;
13384       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13385         ;
13386       else if (unformat (line_input, "vni %d", &vni))
13387         vni_set = 1;
13388       else if (unformat (line_input, "next-ip4"))
13389         protocol = 1;
13390       else if (unformat (line_input, "next-ip6"))
13391         protocol = 2;
13392       else if (unformat (line_input, "next-ethernet"))
13393         protocol = 3;
13394       else if (unformat (line_input, "next-nsh"))
13395         protocol = 4;
13396       else
13397         {
13398           errmsg ("parse error '%U'", format_unformat_error, line_input);
13399           return -99;
13400         }
13401     }
13402
13403   if (local_set == 0)
13404     {
13405       errmsg ("tunnel local address not specified");
13406       return -99;
13407     }
13408   if (remote_set == 0)
13409     {
13410       errmsg ("tunnel remote address not specified");
13411       return -99;
13412     }
13413   if (grp_set && mcast_sw_if_index == ~0)
13414     {
13415       errmsg ("tunnel nonexistent multicast device");
13416       return -99;
13417     }
13418   if (ipv4_set && ipv6_set)
13419     {
13420       errmsg ("both IPv4 and IPv6 addresses specified");
13421       return -99;
13422     }
13423
13424   if (vni_set == 0)
13425     {
13426       errmsg ("vni not specified");
13427       return -99;
13428     }
13429
13430   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13431
13432
13433   if (ipv6_set)
13434     {
13435       clib_memcpy (&mp->local, &local6, sizeof (local6));
13436       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13437     }
13438   else
13439     {
13440       clib_memcpy (&mp->local, &local4, sizeof (local4));
13441       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13442     }
13443
13444   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13445   mp->encap_vrf_id = ntohl (encap_vrf_id);
13446   mp->decap_vrf_id = ntohl (decap_vrf_id);
13447   mp->protocol = protocol;
13448   mp->vni = ntohl (vni);
13449   mp->is_add = is_add;
13450   mp->is_ipv6 = ipv6_set;
13451
13452   S (mp);
13453   W (ret);
13454   return ret;
13455 }
13456
13457 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13458   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13459 {
13460   vat_main_t *vam = &vat_main;
13461   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13462   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13463
13464   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13465          ntohl (mp->sw_if_index),
13466          format_ip46_address, &local, IP46_TYPE_ANY,
13467          format_ip46_address, &remote, IP46_TYPE_ANY,
13468          ntohl (mp->vni), mp->protocol,
13469          ntohl (mp->mcast_sw_if_index),
13470          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13471 }
13472
13473
13474 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13475   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13476 {
13477   vat_main_t *vam = &vat_main;
13478   vat_json_node_t *node = NULL;
13479   struct in_addr ip4;
13480   struct in6_addr ip6;
13481
13482   if (VAT_JSON_ARRAY != vam->json_tree.type)
13483     {
13484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13485       vat_json_init_array (&vam->json_tree);
13486     }
13487   node = vat_json_array_add (&vam->json_tree);
13488
13489   vat_json_init_object (node);
13490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13491   if (mp->is_ipv6)
13492     {
13493       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13494       vat_json_object_add_ip6 (node, "local", ip6);
13495       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13496       vat_json_object_add_ip6 (node, "remote", ip6);
13497     }
13498   else
13499     {
13500       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13501       vat_json_object_add_ip4 (node, "local", ip4);
13502       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13503       vat_json_object_add_ip4 (node, "remote", ip4);
13504     }
13505   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13506   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13507   vat_json_object_add_uint (node, "mcast_sw_if_index",
13508                             ntohl (mp->mcast_sw_if_index));
13509   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13510   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13511   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13512 }
13513
13514 static int
13515 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13516 {
13517   unformat_input_t *i = vam->input;
13518   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13519   vl_api_control_ping_t *mp_ping;
13520   u32 sw_if_index;
13521   u8 sw_if_index_set = 0;
13522   int ret;
13523
13524   /* Parse args required to build the message */
13525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13526     {
13527       if (unformat (i, "sw_if_index %d", &sw_if_index))
13528         sw_if_index_set = 1;
13529       else
13530         break;
13531     }
13532
13533   if (sw_if_index_set == 0)
13534     {
13535       sw_if_index = ~0;
13536     }
13537
13538   if (!vam->json_output)
13539     {
13540       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13541              "sw_if_index", "local", "remote", "vni",
13542              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13543     }
13544
13545   /* Get list of vxlan-tunnel interfaces */
13546   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13547
13548   mp->sw_if_index = htonl (sw_if_index);
13549
13550   S (mp);
13551
13552   /* Use a control ping for synchronization */
13553   MPING (CONTROL_PING, mp_ping);
13554   S (mp_ping);
13555
13556   W (ret);
13557   return ret;
13558 }
13559
13560 static void vl_api_l2_fib_table_details_t_handler
13561   (vl_api_l2_fib_table_details_t * mp)
13562 {
13563   vat_main_t *vam = &vat_main;
13564
13565   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13566          "       %d       %d     %d",
13567          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13568          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13569          mp->bvi_mac);
13570 }
13571
13572 static void vl_api_l2_fib_table_details_t_handler_json
13573   (vl_api_l2_fib_table_details_t * mp)
13574 {
13575   vat_main_t *vam = &vat_main;
13576   vat_json_node_t *node = NULL;
13577
13578   if (VAT_JSON_ARRAY != vam->json_tree.type)
13579     {
13580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13581       vat_json_init_array (&vam->json_tree);
13582     }
13583   node = vat_json_array_add (&vam->json_tree);
13584
13585   vat_json_init_object (node);
13586   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13587   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13588   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13589   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13590   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13591   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13592 }
13593
13594 static int
13595 api_l2_fib_table_dump (vat_main_t * vam)
13596 {
13597   unformat_input_t *i = vam->input;
13598   vl_api_l2_fib_table_dump_t *mp;
13599   vl_api_control_ping_t *mp_ping;
13600   u32 bd_id;
13601   u8 bd_id_set = 0;
13602   int ret;
13603
13604   /* Parse args required to build the message */
13605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13606     {
13607       if (unformat (i, "bd_id %d", &bd_id))
13608         bd_id_set = 1;
13609       else
13610         break;
13611     }
13612
13613   if (bd_id_set == 0)
13614     {
13615       errmsg ("missing bridge domain");
13616       return -99;
13617     }
13618
13619   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13620
13621   /* Get list of l2 fib entries */
13622   M (L2_FIB_TABLE_DUMP, mp);
13623
13624   mp->bd_id = ntohl (bd_id);
13625   S (mp);
13626
13627   /* Use a control ping for synchronization */
13628   MPING (CONTROL_PING, mp_ping);
13629   S (mp_ping);
13630
13631   W (ret);
13632   return ret;
13633 }
13634
13635
13636 static int
13637 api_interface_name_renumber (vat_main_t * vam)
13638 {
13639   unformat_input_t *line_input = vam->input;
13640   vl_api_interface_name_renumber_t *mp;
13641   u32 sw_if_index = ~0;
13642   u32 new_show_dev_instance = ~0;
13643   int ret;
13644
13645   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13646     {
13647       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13648                     &sw_if_index))
13649         ;
13650       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13651         ;
13652       else if (unformat (line_input, "new_show_dev_instance %d",
13653                          &new_show_dev_instance))
13654         ;
13655       else
13656         break;
13657     }
13658
13659   if (sw_if_index == ~0)
13660     {
13661       errmsg ("missing interface name or sw_if_index");
13662       return -99;
13663     }
13664
13665   if (new_show_dev_instance == ~0)
13666     {
13667       errmsg ("missing new_show_dev_instance");
13668       return -99;
13669     }
13670
13671   M (INTERFACE_NAME_RENUMBER, mp);
13672
13673   mp->sw_if_index = ntohl (sw_if_index);
13674   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13675
13676   S (mp);
13677   W (ret);
13678   return ret;
13679 }
13680
13681 static int
13682 api_want_ip4_arp_events (vat_main_t * vam)
13683 {
13684   unformat_input_t *line_input = vam->input;
13685   vl_api_want_ip4_arp_events_t *mp;
13686   ip4_address_t address;
13687   int address_set = 0;
13688   u32 enable_disable = 1;
13689   int ret;
13690
13691   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13692     {
13693       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13694         address_set = 1;
13695       else if (unformat (line_input, "del"))
13696         enable_disable = 0;
13697       else
13698         break;
13699     }
13700
13701   if (address_set == 0)
13702     {
13703       errmsg ("missing addresses");
13704       return -99;
13705     }
13706
13707   M (WANT_IP4_ARP_EVENTS, mp);
13708   mp->enable_disable = enable_disable;
13709   mp->pid = htonl (getpid ());
13710   mp->address = address.as_u32;
13711
13712   S (mp);
13713   W (ret);
13714   return ret;
13715 }
13716
13717 static int
13718 api_want_ip6_nd_events (vat_main_t * vam)
13719 {
13720   unformat_input_t *line_input = vam->input;
13721   vl_api_want_ip6_nd_events_t *mp;
13722   ip6_address_t address;
13723   int address_set = 0;
13724   u32 enable_disable = 1;
13725   int ret;
13726
13727   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13730         address_set = 1;
13731       else if (unformat (line_input, "del"))
13732         enable_disable = 0;
13733       else
13734         break;
13735     }
13736
13737   if (address_set == 0)
13738     {
13739       errmsg ("missing addresses");
13740       return -99;
13741     }
13742
13743   M (WANT_IP6_ND_EVENTS, mp);
13744   mp->enable_disable = enable_disable;
13745   mp->pid = htonl (getpid ());
13746   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13747
13748   S (mp);
13749   W (ret);
13750   return ret;
13751 }
13752
13753 static int
13754 api_want_l2_macs_events (vat_main_t * vam)
13755 {
13756   unformat_input_t *line_input = vam->input;
13757   vl_api_want_l2_macs_events_t *mp;
13758   u8 enable_disable = 1;
13759   u32 scan_delay = 0;
13760   u32 max_macs_in_event = 0;
13761   u32 learn_limit = 0;
13762   int ret;
13763
13764   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13765     {
13766       if (unformat (line_input, "learn-limit %d", &learn_limit))
13767         ;
13768       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13769         ;
13770       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13771         ;
13772       else if (unformat (line_input, "disable"))
13773         enable_disable = 0;
13774       else
13775         break;
13776     }
13777
13778   M (WANT_L2_MACS_EVENTS, mp);
13779   mp->enable_disable = enable_disable;
13780   mp->pid = htonl (getpid ());
13781   mp->learn_limit = htonl (learn_limit);
13782   mp->scan_delay = (u8) scan_delay;
13783   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13784   S (mp);
13785   W (ret);
13786   return ret;
13787 }
13788
13789 static int
13790 api_input_acl_set_interface (vat_main_t * vam)
13791 {
13792   unformat_input_t *i = vam->input;
13793   vl_api_input_acl_set_interface_t *mp;
13794   u32 sw_if_index;
13795   int sw_if_index_set;
13796   u32 ip4_table_index = ~0;
13797   u32 ip6_table_index = ~0;
13798   u32 l2_table_index = ~0;
13799   u8 is_add = 1;
13800   int ret;
13801
13802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13803     {
13804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13805         sw_if_index_set = 1;
13806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13807         sw_if_index_set = 1;
13808       else if (unformat (i, "del"))
13809         is_add = 0;
13810       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13811         ;
13812       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13813         ;
13814       else if (unformat (i, "l2-table %d", &l2_table_index))
13815         ;
13816       else
13817         {
13818           clib_warning ("parse error '%U'", format_unformat_error, i);
13819           return -99;
13820         }
13821     }
13822
13823   if (sw_if_index_set == 0)
13824     {
13825       errmsg ("missing interface name or sw_if_index");
13826       return -99;
13827     }
13828
13829   M (INPUT_ACL_SET_INTERFACE, mp);
13830
13831   mp->sw_if_index = ntohl (sw_if_index);
13832   mp->ip4_table_index = ntohl (ip4_table_index);
13833   mp->ip6_table_index = ntohl (ip6_table_index);
13834   mp->l2_table_index = ntohl (l2_table_index);
13835   mp->is_add = is_add;
13836
13837   S (mp);
13838   W (ret);
13839   return ret;
13840 }
13841
13842 static int
13843 api_ip_address_dump (vat_main_t * vam)
13844 {
13845   unformat_input_t *i = vam->input;
13846   vl_api_ip_address_dump_t *mp;
13847   vl_api_control_ping_t *mp_ping;
13848   u32 sw_if_index = ~0;
13849   u8 sw_if_index_set = 0;
13850   u8 ipv4_set = 0;
13851   u8 ipv6_set = 0;
13852   int ret;
13853
13854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13855     {
13856       if (unformat (i, "sw_if_index %d", &sw_if_index))
13857         sw_if_index_set = 1;
13858       else
13859         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13860         sw_if_index_set = 1;
13861       else if (unformat (i, "ipv4"))
13862         ipv4_set = 1;
13863       else if (unformat (i, "ipv6"))
13864         ipv6_set = 1;
13865       else
13866         break;
13867     }
13868
13869   if (ipv4_set && ipv6_set)
13870     {
13871       errmsg ("ipv4 and ipv6 flags cannot be both set");
13872       return -99;
13873     }
13874
13875   if ((!ipv4_set) && (!ipv6_set))
13876     {
13877       errmsg ("no ipv4 nor ipv6 flag set");
13878       return -99;
13879     }
13880
13881   if (sw_if_index_set == 0)
13882     {
13883       errmsg ("missing interface name or sw_if_index");
13884       return -99;
13885     }
13886
13887   vam->current_sw_if_index = sw_if_index;
13888   vam->is_ipv6 = ipv6_set;
13889
13890   M (IP_ADDRESS_DUMP, mp);
13891   mp->sw_if_index = ntohl (sw_if_index);
13892   mp->is_ipv6 = ipv6_set;
13893   S (mp);
13894
13895   /* Use a control ping for synchronization */
13896   MPING (CONTROL_PING, mp_ping);
13897   S (mp_ping);
13898
13899   W (ret);
13900   return ret;
13901 }
13902
13903 static int
13904 api_ip_dump (vat_main_t * vam)
13905 {
13906   vl_api_ip_dump_t *mp;
13907   vl_api_control_ping_t *mp_ping;
13908   unformat_input_t *in = vam->input;
13909   int ipv4_set = 0;
13910   int ipv6_set = 0;
13911   int is_ipv6;
13912   int i;
13913   int ret;
13914
13915   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (in, "ipv4"))
13918         ipv4_set = 1;
13919       else if (unformat (in, "ipv6"))
13920         ipv6_set = 1;
13921       else
13922         break;
13923     }
13924
13925   if (ipv4_set && ipv6_set)
13926     {
13927       errmsg ("ipv4 and ipv6 flags cannot be both set");
13928       return -99;
13929     }
13930
13931   if ((!ipv4_set) && (!ipv6_set))
13932     {
13933       errmsg ("no ipv4 nor ipv6 flag set");
13934       return -99;
13935     }
13936
13937   is_ipv6 = ipv6_set;
13938   vam->is_ipv6 = is_ipv6;
13939
13940   /* free old data */
13941   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13942     {
13943       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13944     }
13945   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13946
13947   M (IP_DUMP, mp);
13948   mp->is_ipv6 = ipv6_set;
13949   S (mp);
13950
13951   /* Use a control ping for synchronization */
13952   MPING (CONTROL_PING, mp_ping);
13953   S (mp_ping);
13954
13955   W (ret);
13956   return ret;
13957 }
13958
13959 static int
13960 api_ipsec_spd_add_del (vat_main_t * vam)
13961 {
13962   unformat_input_t *i = vam->input;
13963   vl_api_ipsec_spd_add_del_t *mp;
13964   u32 spd_id = ~0;
13965   u8 is_add = 1;
13966   int ret;
13967
13968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (unformat (i, "spd_id %d", &spd_id))
13971         ;
13972       else if (unformat (i, "del"))
13973         is_add = 0;
13974       else
13975         {
13976           clib_warning ("parse error '%U'", format_unformat_error, i);
13977           return -99;
13978         }
13979     }
13980   if (spd_id == ~0)
13981     {
13982       errmsg ("spd_id must be set");
13983       return -99;
13984     }
13985
13986   M (IPSEC_SPD_ADD_DEL, mp);
13987
13988   mp->spd_id = ntohl (spd_id);
13989   mp->is_add = is_add;
13990
13991   S (mp);
13992   W (ret);
13993   return ret;
13994 }
13995
13996 static int
13997 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13998 {
13999   unformat_input_t *i = vam->input;
14000   vl_api_ipsec_interface_add_del_spd_t *mp;
14001   u32 sw_if_index;
14002   u8 sw_if_index_set = 0;
14003   u32 spd_id = (u32) ~ 0;
14004   u8 is_add = 1;
14005   int ret;
14006
14007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (i, "del"))
14010         is_add = 0;
14011       else if (unformat (i, "spd_id %d", &spd_id))
14012         ;
14013       else
14014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14015         sw_if_index_set = 1;
14016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14017         sw_if_index_set = 1;
14018       else
14019         {
14020           clib_warning ("parse error '%U'", format_unformat_error, i);
14021           return -99;
14022         }
14023
14024     }
14025
14026   if (spd_id == (u32) ~ 0)
14027     {
14028       errmsg ("spd_id must be set");
14029       return -99;
14030     }
14031
14032   if (sw_if_index_set == 0)
14033     {
14034       errmsg ("missing interface name or sw_if_index");
14035       return -99;
14036     }
14037
14038   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14039
14040   mp->spd_id = ntohl (spd_id);
14041   mp->sw_if_index = ntohl (sw_if_index);
14042   mp->is_add = is_add;
14043
14044   S (mp);
14045   W (ret);
14046   return ret;
14047 }
14048
14049 static int
14050 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14051 {
14052   unformat_input_t *i = vam->input;
14053   vl_api_ipsec_spd_add_del_entry_t *mp;
14054   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14055   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14056   i32 priority = 0;
14057   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14058   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14059   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14060   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14061   int ret;
14062
14063   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14064   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14065   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14066   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14067   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14068   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14069
14070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14071     {
14072       if (unformat (i, "del"))
14073         is_add = 0;
14074       if (unformat (i, "outbound"))
14075         is_outbound = 1;
14076       if (unformat (i, "inbound"))
14077         is_outbound = 0;
14078       else if (unformat (i, "spd_id %d", &spd_id))
14079         ;
14080       else if (unformat (i, "sa_id %d", &sa_id))
14081         ;
14082       else if (unformat (i, "priority %d", &priority))
14083         ;
14084       else if (unformat (i, "protocol %d", &protocol))
14085         ;
14086       else if (unformat (i, "lport_start %d", &lport_start))
14087         ;
14088       else if (unformat (i, "lport_stop %d", &lport_stop))
14089         ;
14090       else if (unformat (i, "rport_start %d", &rport_start))
14091         ;
14092       else if (unformat (i, "rport_stop %d", &rport_stop))
14093         ;
14094       else
14095         if (unformat
14096             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14097         {
14098           is_ipv6 = 0;
14099           is_ip_any = 0;
14100         }
14101       else
14102         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14103         {
14104           is_ipv6 = 0;
14105           is_ip_any = 0;
14106         }
14107       else
14108         if (unformat
14109             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14110         {
14111           is_ipv6 = 0;
14112           is_ip_any = 0;
14113         }
14114       else
14115         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14116         {
14117           is_ipv6 = 0;
14118           is_ip_any = 0;
14119         }
14120       else
14121         if (unformat
14122             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14123         {
14124           is_ipv6 = 1;
14125           is_ip_any = 0;
14126         }
14127       else
14128         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14129         {
14130           is_ipv6 = 1;
14131           is_ip_any = 0;
14132         }
14133       else
14134         if (unformat
14135             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14136         {
14137           is_ipv6 = 1;
14138           is_ip_any = 0;
14139         }
14140       else
14141         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14142         {
14143           is_ipv6 = 1;
14144           is_ip_any = 0;
14145         }
14146       else
14147         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14148         {
14149           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14150             {
14151               clib_warning ("unsupported action: 'resolve'");
14152               return -99;
14153             }
14154         }
14155       else
14156         {
14157           clib_warning ("parse error '%U'", format_unformat_error, i);
14158           return -99;
14159         }
14160
14161     }
14162
14163   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14164
14165   mp->spd_id = ntohl (spd_id);
14166   mp->priority = ntohl (priority);
14167   mp->is_outbound = is_outbound;
14168
14169   mp->is_ipv6 = is_ipv6;
14170   if (is_ipv6 || is_ip_any)
14171     {
14172       clib_memcpy (mp->remote_address_start, &raddr6_start,
14173                    sizeof (ip6_address_t));
14174       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14175                    sizeof (ip6_address_t));
14176       clib_memcpy (mp->local_address_start, &laddr6_start,
14177                    sizeof (ip6_address_t));
14178       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14179                    sizeof (ip6_address_t));
14180     }
14181   else
14182     {
14183       clib_memcpy (mp->remote_address_start, &raddr4_start,
14184                    sizeof (ip4_address_t));
14185       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14186                    sizeof (ip4_address_t));
14187       clib_memcpy (mp->local_address_start, &laddr4_start,
14188                    sizeof (ip4_address_t));
14189       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14190                    sizeof (ip4_address_t));
14191     }
14192   mp->protocol = (u8) protocol;
14193   mp->local_port_start = ntohs ((u16) lport_start);
14194   mp->local_port_stop = ntohs ((u16) lport_stop);
14195   mp->remote_port_start = ntohs ((u16) rport_start);
14196   mp->remote_port_stop = ntohs ((u16) rport_stop);
14197   mp->policy = (u8) policy;
14198   mp->sa_id = ntohl (sa_id);
14199   mp->is_add = is_add;
14200   mp->is_ip_any = is_ip_any;
14201   S (mp);
14202   W (ret);
14203   return ret;
14204 }
14205
14206 static int
14207 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14208 {
14209   unformat_input_t *i = vam->input;
14210   vl_api_ipsec_sad_add_del_entry_t *mp;
14211   u32 sad_id = 0, spi = 0;
14212   u8 *ck = 0, *ik = 0;
14213   u8 is_add = 1;
14214
14215   u8 protocol = IPSEC_PROTOCOL_AH;
14216   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14217   u32 crypto_alg = 0, integ_alg = 0;
14218   ip4_address_t tun_src4;
14219   ip4_address_t tun_dst4;
14220   ip6_address_t tun_src6;
14221   ip6_address_t tun_dst6;
14222   int ret;
14223
14224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14225     {
14226       if (unformat (i, "del"))
14227         is_add = 0;
14228       else if (unformat (i, "sad_id %d", &sad_id))
14229         ;
14230       else if (unformat (i, "spi %d", &spi))
14231         ;
14232       else if (unformat (i, "esp"))
14233         protocol = IPSEC_PROTOCOL_ESP;
14234       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14235         {
14236           is_tunnel = 1;
14237           is_tunnel_ipv6 = 0;
14238         }
14239       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14240         {
14241           is_tunnel = 1;
14242           is_tunnel_ipv6 = 0;
14243         }
14244       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14245         {
14246           is_tunnel = 1;
14247           is_tunnel_ipv6 = 1;
14248         }
14249       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14250         {
14251           is_tunnel = 1;
14252           is_tunnel_ipv6 = 1;
14253         }
14254       else
14255         if (unformat
14256             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14257         {
14258           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14259               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14260             {
14261               clib_warning ("unsupported crypto-alg: '%U'",
14262                             format_ipsec_crypto_alg, crypto_alg);
14263               return -99;
14264             }
14265         }
14266       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14267         ;
14268       else
14269         if (unformat
14270             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14271         {
14272           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14273               integ_alg >= IPSEC_INTEG_N_ALG)
14274             {
14275               clib_warning ("unsupported integ-alg: '%U'",
14276                             format_ipsec_integ_alg, integ_alg);
14277               return -99;
14278             }
14279         }
14280       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14281         ;
14282       else
14283         {
14284           clib_warning ("parse error '%U'", format_unformat_error, i);
14285           return -99;
14286         }
14287
14288     }
14289
14290   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14291
14292   mp->sad_id = ntohl (sad_id);
14293   mp->is_add = is_add;
14294   mp->protocol = protocol;
14295   mp->spi = ntohl (spi);
14296   mp->is_tunnel = is_tunnel;
14297   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14298   mp->crypto_algorithm = crypto_alg;
14299   mp->integrity_algorithm = integ_alg;
14300   mp->crypto_key_length = vec_len (ck);
14301   mp->integrity_key_length = vec_len (ik);
14302
14303   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14304     mp->crypto_key_length = sizeof (mp->crypto_key);
14305
14306   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14307     mp->integrity_key_length = sizeof (mp->integrity_key);
14308
14309   if (ck)
14310     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14311   if (ik)
14312     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14313
14314   if (is_tunnel)
14315     {
14316       if (is_tunnel_ipv6)
14317         {
14318           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14319                        sizeof (ip6_address_t));
14320           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14321                        sizeof (ip6_address_t));
14322         }
14323       else
14324         {
14325           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14326                        sizeof (ip4_address_t));
14327           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14328                        sizeof (ip4_address_t));
14329         }
14330     }
14331
14332   S (mp);
14333   W (ret);
14334   return ret;
14335 }
14336
14337 static int
14338 api_ipsec_sa_set_key (vat_main_t * vam)
14339 {
14340   unformat_input_t *i = vam->input;
14341   vl_api_ipsec_sa_set_key_t *mp;
14342   u32 sa_id;
14343   u8 *ck = 0, *ik = 0;
14344   int ret;
14345
14346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14347     {
14348       if (unformat (i, "sa_id %d", &sa_id))
14349         ;
14350       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14351         ;
14352       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14353         ;
14354       else
14355         {
14356           clib_warning ("parse error '%U'", format_unformat_error, i);
14357           return -99;
14358         }
14359     }
14360
14361   M (IPSEC_SA_SET_KEY, mp);
14362
14363   mp->sa_id = ntohl (sa_id);
14364   mp->crypto_key_length = vec_len (ck);
14365   mp->integrity_key_length = vec_len (ik);
14366
14367   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14368     mp->crypto_key_length = sizeof (mp->crypto_key);
14369
14370   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14371     mp->integrity_key_length = sizeof (mp->integrity_key);
14372
14373   if (ck)
14374     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14375   if (ik)
14376     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14377
14378   S (mp);
14379   W (ret);
14380   return ret;
14381 }
14382
14383 static int
14384 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14385 {
14386   unformat_input_t *i = vam->input;
14387   vl_api_ipsec_tunnel_if_add_del_t *mp;
14388   u32 local_spi = 0, remote_spi = 0;
14389   u32 crypto_alg = 0, integ_alg = 0;
14390   u8 *lck = NULL, *rck = NULL;
14391   u8 *lik = NULL, *rik = NULL;
14392   ip4_address_t local_ip = { {0} };
14393   ip4_address_t remote_ip = { {0} };
14394   u8 is_add = 1;
14395   u8 esn = 0;
14396   u8 anti_replay = 0;
14397   int ret;
14398
14399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat (i, "del"))
14402         is_add = 0;
14403       else if (unformat (i, "esn"))
14404         esn = 1;
14405       else if (unformat (i, "anti_replay"))
14406         anti_replay = 1;
14407       else if (unformat (i, "local_spi %d", &local_spi))
14408         ;
14409       else if (unformat (i, "remote_spi %d", &remote_spi))
14410         ;
14411       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14412         ;
14413       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14414         ;
14415       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14416         ;
14417       else
14418         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14419         ;
14420       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14421         ;
14422       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14423         ;
14424       else
14425         if (unformat
14426             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14427         {
14428           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14429               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14430             {
14431               errmsg ("unsupported crypto-alg: '%U'\n",
14432                       format_ipsec_crypto_alg, crypto_alg);
14433               return -99;
14434             }
14435         }
14436       else
14437         if (unformat
14438             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14439         {
14440           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14441               integ_alg >= IPSEC_INTEG_N_ALG)
14442             {
14443               errmsg ("unsupported integ-alg: '%U'\n",
14444                       format_ipsec_integ_alg, integ_alg);
14445               return -99;
14446             }
14447         }
14448       else
14449         {
14450           errmsg ("parse error '%U'\n", format_unformat_error, i);
14451           return -99;
14452         }
14453     }
14454
14455   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14456
14457   mp->is_add = is_add;
14458   mp->esn = esn;
14459   mp->anti_replay = anti_replay;
14460
14461   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14462   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14463
14464   mp->local_spi = htonl (local_spi);
14465   mp->remote_spi = htonl (remote_spi);
14466   mp->crypto_alg = (u8) crypto_alg;
14467
14468   mp->local_crypto_key_len = 0;
14469   if (lck)
14470     {
14471       mp->local_crypto_key_len = vec_len (lck);
14472       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14473         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14474       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14475     }
14476
14477   mp->remote_crypto_key_len = 0;
14478   if (rck)
14479     {
14480       mp->remote_crypto_key_len = vec_len (rck);
14481       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14482         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14483       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14484     }
14485
14486   mp->integ_alg = (u8) integ_alg;
14487
14488   mp->local_integ_key_len = 0;
14489   if (lik)
14490     {
14491       mp->local_integ_key_len = vec_len (lik);
14492       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14493         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14494       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14495     }
14496
14497   mp->remote_integ_key_len = 0;
14498   if (rik)
14499     {
14500       mp->remote_integ_key_len = vec_len (rik);
14501       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14502         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14503       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14504     }
14505
14506   S (mp);
14507   W (ret);
14508   return ret;
14509 }
14510
14511 static void
14512 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14513 {
14514   vat_main_t *vam = &vat_main;
14515
14516   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14517          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14518          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14519          "tunnel_src_addr %U tunnel_dst_addr %U "
14520          "salt %u seq_outbound %lu last_seq_inbound %lu "
14521          "replay_window %lu total_data_size %lu\n",
14522          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14523          mp->protocol,
14524          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14525          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14526          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14527          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14528          mp->tunnel_src_addr,
14529          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14530          mp->tunnel_dst_addr,
14531          ntohl (mp->salt),
14532          clib_net_to_host_u64 (mp->seq_outbound),
14533          clib_net_to_host_u64 (mp->last_seq_inbound),
14534          clib_net_to_host_u64 (mp->replay_window),
14535          clib_net_to_host_u64 (mp->total_data_size));
14536 }
14537
14538 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14539 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14540
14541 static void vl_api_ipsec_sa_details_t_handler_json
14542   (vl_api_ipsec_sa_details_t * mp)
14543 {
14544   vat_main_t *vam = &vat_main;
14545   vat_json_node_t *node = NULL;
14546   struct in_addr src_ip4, dst_ip4;
14547   struct in6_addr src_ip6, dst_ip6;
14548
14549   if (VAT_JSON_ARRAY != vam->json_tree.type)
14550     {
14551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14552       vat_json_init_array (&vam->json_tree);
14553     }
14554   node = vat_json_array_add (&vam->json_tree);
14555
14556   vat_json_init_object (node);
14557   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14558   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14559   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14560   vat_json_object_add_uint (node, "proto", mp->protocol);
14561   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14562   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14563   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14564   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14565   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14566   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14567   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14568                              mp->crypto_key_len);
14569   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14570                              mp->integ_key_len);
14571   if (mp->is_tunnel_ip6)
14572     {
14573       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14574       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14575       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14576       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14577     }
14578   else
14579     {
14580       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14581       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14582       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14583       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14584     }
14585   vat_json_object_add_uint (node, "replay_window",
14586                             clib_net_to_host_u64 (mp->replay_window));
14587   vat_json_object_add_uint (node, "total_data_size",
14588                             clib_net_to_host_u64 (mp->total_data_size));
14589
14590 }
14591
14592 static int
14593 api_ipsec_sa_dump (vat_main_t * vam)
14594 {
14595   unformat_input_t *i = vam->input;
14596   vl_api_ipsec_sa_dump_t *mp;
14597   vl_api_control_ping_t *mp_ping;
14598   u32 sa_id = ~0;
14599   int ret;
14600
14601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14602     {
14603       if (unformat (i, "sa_id %d", &sa_id))
14604         ;
14605       else
14606         {
14607           clib_warning ("parse error '%U'", format_unformat_error, i);
14608           return -99;
14609         }
14610     }
14611
14612   M (IPSEC_SA_DUMP, mp);
14613
14614   mp->sa_id = ntohl (sa_id);
14615
14616   S (mp);
14617
14618   /* Use a control ping for synchronization */
14619   M (CONTROL_PING, mp_ping);
14620   S (mp_ping);
14621
14622   W (ret);
14623   return ret;
14624 }
14625
14626 static int
14627 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14628 {
14629   unformat_input_t *i = vam->input;
14630   vl_api_ipsec_tunnel_if_set_key_t *mp;
14631   u32 sw_if_index = ~0;
14632   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14633   u8 *key = 0;
14634   u32 alg = ~0;
14635   int ret;
14636
14637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14638     {
14639       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14640         ;
14641       else
14642         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14643         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14644       else
14645         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14646         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14647       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14648         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14649       else
14650         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14651         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14652       else if (unformat (i, "%U", unformat_hex_string, &key))
14653         ;
14654       else
14655         {
14656           clib_warning ("parse error '%U'", format_unformat_error, i);
14657           return -99;
14658         }
14659     }
14660
14661   if (sw_if_index == ~0)
14662     {
14663       errmsg ("interface must be specified");
14664       return -99;
14665     }
14666
14667   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14668     {
14669       errmsg ("key type must be specified");
14670       return -99;
14671     }
14672
14673   if (alg == ~0)
14674     {
14675       errmsg ("algorithm must be specified");
14676       return -99;
14677     }
14678
14679   if (vec_len (key) == 0)
14680     {
14681       errmsg ("key must be specified");
14682       return -99;
14683     }
14684
14685   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14686
14687   mp->sw_if_index = htonl (sw_if_index);
14688   mp->alg = alg;
14689   mp->key_type = key_type;
14690   mp->key_len = vec_len (key);
14691   clib_memcpy (mp->key, key, vec_len (key));
14692
14693   S (mp);
14694   W (ret);
14695
14696   return ret;
14697 }
14698
14699 static int
14700 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14701 {
14702   unformat_input_t *i = vam->input;
14703   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14704   u32 sw_if_index = ~0;
14705   u32 sa_id = ~0;
14706   u8 is_outbound = (u8) ~ 0;
14707   int ret;
14708
14709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14710     {
14711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14712         ;
14713       else if (unformat (i, "sa_id %d", &sa_id))
14714         ;
14715       else if (unformat (i, "outbound"))
14716         is_outbound = 1;
14717       else if (unformat (i, "inbound"))
14718         is_outbound = 0;
14719       else
14720         {
14721           clib_warning ("parse error '%U'", format_unformat_error, i);
14722           return -99;
14723         }
14724     }
14725
14726   if (sw_if_index == ~0)
14727     {
14728       errmsg ("interface must be specified");
14729       return -99;
14730     }
14731
14732   if (sa_id == ~0)
14733     {
14734       errmsg ("SA ID must be specified");
14735       return -99;
14736     }
14737
14738   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14739
14740   mp->sw_if_index = htonl (sw_if_index);
14741   mp->sa_id = htonl (sa_id);
14742   mp->is_outbound = is_outbound;
14743
14744   S (mp);
14745   W (ret);
14746
14747   return ret;
14748 }
14749
14750 static int
14751 api_ikev2_profile_add_del (vat_main_t * vam)
14752 {
14753   unformat_input_t *i = vam->input;
14754   vl_api_ikev2_profile_add_del_t *mp;
14755   u8 is_add = 1;
14756   u8 *name = 0;
14757   int ret;
14758
14759   const char *valid_chars = "a-zA-Z0-9_";
14760
14761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14762     {
14763       if (unformat (i, "del"))
14764         is_add = 0;
14765       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14766         vec_add1 (name, 0);
14767       else
14768         {
14769           errmsg ("parse error '%U'", format_unformat_error, i);
14770           return -99;
14771         }
14772     }
14773
14774   if (!vec_len (name))
14775     {
14776       errmsg ("profile name must be specified");
14777       return -99;
14778     }
14779
14780   if (vec_len (name) > 64)
14781     {
14782       errmsg ("profile name too long");
14783       return -99;
14784     }
14785
14786   M (IKEV2_PROFILE_ADD_DEL, mp);
14787
14788   clib_memcpy (mp->name, name, vec_len (name));
14789   mp->is_add = is_add;
14790   vec_free (name);
14791
14792   S (mp);
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_ikev2_profile_set_auth (vat_main_t * vam)
14799 {
14800   unformat_input_t *i = vam->input;
14801   vl_api_ikev2_profile_set_auth_t *mp;
14802   u8 *name = 0;
14803   u8 *data = 0;
14804   u32 auth_method = 0;
14805   u8 is_hex = 0;
14806   int ret;
14807
14808   const char *valid_chars = "a-zA-Z0-9_";
14809
14810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14811     {
14812       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14813         vec_add1 (name, 0);
14814       else if (unformat (i, "auth_method %U",
14815                          unformat_ikev2_auth_method, &auth_method))
14816         ;
14817       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14818         is_hex = 1;
14819       else if (unformat (i, "auth_data %v", &data))
14820         ;
14821       else
14822         {
14823           errmsg ("parse error '%U'", format_unformat_error, i);
14824           return -99;
14825         }
14826     }
14827
14828   if (!vec_len (name))
14829     {
14830       errmsg ("profile name must be specified");
14831       return -99;
14832     }
14833
14834   if (vec_len (name) > 64)
14835     {
14836       errmsg ("profile name too long");
14837       return -99;
14838     }
14839
14840   if (!vec_len (data))
14841     {
14842       errmsg ("auth_data must be specified");
14843       return -99;
14844     }
14845
14846   if (!auth_method)
14847     {
14848       errmsg ("auth_method must be specified");
14849       return -99;
14850     }
14851
14852   M (IKEV2_PROFILE_SET_AUTH, mp);
14853
14854   mp->is_hex = is_hex;
14855   mp->auth_method = (u8) auth_method;
14856   mp->data_len = vec_len (data);
14857   clib_memcpy (mp->name, name, vec_len (name));
14858   clib_memcpy (mp->data, data, vec_len (data));
14859   vec_free (name);
14860   vec_free (data);
14861
14862   S (mp);
14863   W (ret);
14864   return ret;
14865 }
14866
14867 static int
14868 api_ikev2_profile_set_id (vat_main_t * vam)
14869 {
14870   unformat_input_t *i = vam->input;
14871   vl_api_ikev2_profile_set_id_t *mp;
14872   u8 *name = 0;
14873   u8 *data = 0;
14874   u8 is_local = 0;
14875   u32 id_type = 0;
14876   ip4_address_t ip4;
14877   int ret;
14878
14879   const char *valid_chars = "a-zA-Z0-9_";
14880
14881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14882     {
14883       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14884         vec_add1 (name, 0);
14885       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14886         ;
14887       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14888         {
14889           data = vec_new (u8, 4);
14890           clib_memcpy (data, ip4.as_u8, 4);
14891         }
14892       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14893         ;
14894       else if (unformat (i, "id_data %v", &data))
14895         ;
14896       else if (unformat (i, "local"))
14897         is_local = 1;
14898       else if (unformat (i, "remote"))
14899         is_local = 0;
14900       else
14901         {
14902           errmsg ("parse error '%U'", format_unformat_error, i);
14903           return -99;
14904         }
14905     }
14906
14907   if (!vec_len (name))
14908     {
14909       errmsg ("profile name must be specified");
14910       return -99;
14911     }
14912
14913   if (vec_len (name) > 64)
14914     {
14915       errmsg ("profile name too long");
14916       return -99;
14917     }
14918
14919   if (!vec_len (data))
14920     {
14921       errmsg ("id_data must be specified");
14922       return -99;
14923     }
14924
14925   if (!id_type)
14926     {
14927       errmsg ("id_type must be specified");
14928       return -99;
14929     }
14930
14931   M (IKEV2_PROFILE_SET_ID, mp);
14932
14933   mp->is_local = is_local;
14934   mp->id_type = (u8) id_type;
14935   mp->data_len = vec_len (data);
14936   clib_memcpy (mp->name, name, vec_len (name));
14937   clib_memcpy (mp->data, data, vec_len (data));
14938   vec_free (name);
14939   vec_free (data);
14940
14941   S (mp);
14942   W (ret);
14943   return ret;
14944 }
14945
14946 static int
14947 api_ikev2_profile_set_ts (vat_main_t * vam)
14948 {
14949   unformat_input_t *i = vam->input;
14950   vl_api_ikev2_profile_set_ts_t *mp;
14951   u8 *name = 0;
14952   u8 is_local = 0;
14953   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14954   ip4_address_t start_addr, end_addr;
14955
14956   const char *valid_chars = "a-zA-Z0-9_";
14957   int ret;
14958
14959   start_addr.as_u32 = 0;
14960   end_addr.as_u32 = (u32) ~ 0;
14961
14962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14963     {
14964       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14965         vec_add1 (name, 0);
14966       else if (unformat (i, "protocol %d", &proto))
14967         ;
14968       else if (unformat (i, "start_port %d", &start_port))
14969         ;
14970       else if (unformat (i, "end_port %d", &end_port))
14971         ;
14972       else
14973         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14974         ;
14975       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14976         ;
14977       else if (unformat (i, "local"))
14978         is_local = 1;
14979       else if (unformat (i, "remote"))
14980         is_local = 0;
14981       else
14982         {
14983           errmsg ("parse error '%U'", format_unformat_error, i);
14984           return -99;
14985         }
14986     }
14987
14988   if (!vec_len (name))
14989     {
14990       errmsg ("profile name must be specified");
14991       return -99;
14992     }
14993
14994   if (vec_len (name) > 64)
14995     {
14996       errmsg ("profile name too long");
14997       return -99;
14998     }
14999
15000   M (IKEV2_PROFILE_SET_TS, mp);
15001
15002   mp->is_local = is_local;
15003   mp->proto = (u8) proto;
15004   mp->start_port = (u16) start_port;
15005   mp->end_port = (u16) end_port;
15006   mp->start_addr = start_addr.as_u32;
15007   mp->end_addr = end_addr.as_u32;
15008   clib_memcpy (mp->name, name, vec_len (name));
15009   vec_free (name);
15010
15011   S (mp);
15012   W (ret);
15013   return ret;
15014 }
15015
15016 static int
15017 api_ikev2_set_local_key (vat_main_t * vam)
15018 {
15019   unformat_input_t *i = vam->input;
15020   vl_api_ikev2_set_local_key_t *mp;
15021   u8 *file = 0;
15022   int ret;
15023
15024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15025     {
15026       if (unformat (i, "file %v", &file))
15027         vec_add1 (file, 0);
15028       else
15029         {
15030           errmsg ("parse error '%U'", format_unformat_error, i);
15031           return -99;
15032         }
15033     }
15034
15035   if (!vec_len (file))
15036     {
15037       errmsg ("RSA key file must be specified");
15038       return -99;
15039     }
15040
15041   if (vec_len (file) > 256)
15042     {
15043       errmsg ("file name too long");
15044       return -99;
15045     }
15046
15047   M (IKEV2_SET_LOCAL_KEY, mp);
15048
15049   clib_memcpy (mp->key_file, file, vec_len (file));
15050   vec_free (file);
15051
15052   S (mp);
15053   W (ret);
15054   return ret;
15055 }
15056
15057 static int
15058 api_ikev2_set_responder (vat_main_t * vam)
15059 {
15060   unformat_input_t *i = vam->input;
15061   vl_api_ikev2_set_responder_t *mp;
15062   int ret;
15063   u8 *name = 0;
15064   u32 sw_if_index = ~0;
15065   ip4_address_t address;
15066
15067   const char *valid_chars = "a-zA-Z0-9_";
15068
15069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15070     {
15071       if (unformat
15072           (i, "%U interface %d address %U", unformat_token, valid_chars,
15073            &name, &sw_if_index, unformat_ip4_address, &address))
15074         vec_add1 (name, 0);
15075       else
15076         {
15077           errmsg ("parse error '%U'", format_unformat_error, i);
15078           return -99;
15079         }
15080     }
15081
15082   if (!vec_len (name))
15083     {
15084       errmsg ("profile name must be specified");
15085       return -99;
15086     }
15087
15088   if (vec_len (name) > 64)
15089     {
15090       errmsg ("profile name too long");
15091       return -99;
15092     }
15093
15094   M (IKEV2_SET_RESPONDER, mp);
15095
15096   clib_memcpy (mp->name, name, vec_len (name));
15097   vec_free (name);
15098
15099   mp->sw_if_index = sw_if_index;
15100   clib_memcpy (mp->address, &address, sizeof (address));
15101
15102   S (mp);
15103   W (ret);
15104   return ret;
15105 }
15106
15107 static int
15108 api_ikev2_set_ike_transforms (vat_main_t * vam)
15109 {
15110   unformat_input_t *i = vam->input;
15111   vl_api_ikev2_set_ike_transforms_t *mp;
15112   int ret;
15113   u8 *name = 0;
15114   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15115
15116   const char *valid_chars = "a-zA-Z0-9_";
15117
15118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15119     {
15120       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15121                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15122         vec_add1 (name, 0);
15123       else
15124         {
15125           errmsg ("parse error '%U'", format_unformat_error, i);
15126           return -99;
15127         }
15128     }
15129
15130   if (!vec_len (name))
15131     {
15132       errmsg ("profile name must be specified");
15133       return -99;
15134     }
15135
15136   if (vec_len (name) > 64)
15137     {
15138       errmsg ("profile name too long");
15139       return -99;
15140     }
15141
15142   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15143
15144   clib_memcpy (mp->name, name, vec_len (name));
15145   vec_free (name);
15146   mp->crypto_alg = crypto_alg;
15147   mp->crypto_key_size = crypto_key_size;
15148   mp->integ_alg = integ_alg;
15149   mp->dh_group = dh_group;
15150
15151   S (mp);
15152   W (ret);
15153   return ret;
15154 }
15155
15156
15157 static int
15158 api_ikev2_set_esp_transforms (vat_main_t * vam)
15159 {
15160   unformat_input_t *i = vam->input;
15161   vl_api_ikev2_set_esp_transforms_t *mp;
15162   int ret;
15163   u8 *name = 0;
15164   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15165
15166   const char *valid_chars = "a-zA-Z0-9_";
15167
15168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15169     {
15170       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15171                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15172         vec_add1 (name, 0);
15173       else
15174         {
15175           errmsg ("parse error '%U'", format_unformat_error, i);
15176           return -99;
15177         }
15178     }
15179
15180   if (!vec_len (name))
15181     {
15182       errmsg ("profile name must be specified");
15183       return -99;
15184     }
15185
15186   if (vec_len (name) > 64)
15187     {
15188       errmsg ("profile name too long");
15189       return -99;
15190     }
15191
15192   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15193
15194   clib_memcpy (mp->name, name, vec_len (name));
15195   vec_free (name);
15196   mp->crypto_alg = crypto_alg;
15197   mp->crypto_key_size = crypto_key_size;
15198   mp->integ_alg = integ_alg;
15199   mp->dh_group = dh_group;
15200
15201   S (mp);
15202   W (ret);
15203   return ret;
15204 }
15205
15206 static int
15207 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15208 {
15209   unformat_input_t *i = vam->input;
15210   vl_api_ikev2_set_sa_lifetime_t *mp;
15211   int ret;
15212   u8 *name = 0;
15213   u64 lifetime, lifetime_maxdata;
15214   u32 lifetime_jitter, handover;
15215
15216   const char *valid_chars = "a-zA-Z0-9_";
15217
15218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15219     {
15220       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15221                     &lifetime, &lifetime_jitter, &handover,
15222                     &lifetime_maxdata))
15223         vec_add1 (name, 0);
15224       else
15225         {
15226           errmsg ("parse error '%U'", format_unformat_error, i);
15227           return -99;
15228         }
15229     }
15230
15231   if (!vec_len (name))
15232     {
15233       errmsg ("profile name must be specified");
15234       return -99;
15235     }
15236
15237   if (vec_len (name) > 64)
15238     {
15239       errmsg ("profile name too long");
15240       return -99;
15241     }
15242
15243   M (IKEV2_SET_SA_LIFETIME, mp);
15244
15245   clib_memcpy (mp->name, name, vec_len (name));
15246   vec_free (name);
15247   mp->lifetime = lifetime;
15248   mp->lifetime_jitter = lifetime_jitter;
15249   mp->handover = handover;
15250   mp->lifetime_maxdata = lifetime_maxdata;
15251
15252   S (mp);
15253   W (ret);
15254   return ret;
15255 }
15256
15257 static int
15258 api_ikev2_initiate_sa_init (vat_main_t * vam)
15259 {
15260   unformat_input_t *i = vam->input;
15261   vl_api_ikev2_initiate_sa_init_t *mp;
15262   int ret;
15263   u8 *name = 0;
15264
15265   const char *valid_chars = "a-zA-Z0-9_";
15266
15267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15268     {
15269       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15270         vec_add1 (name, 0);
15271       else
15272         {
15273           errmsg ("parse error '%U'", format_unformat_error, i);
15274           return -99;
15275         }
15276     }
15277
15278   if (!vec_len (name))
15279     {
15280       errmsg ("profile name must be specified");
15281       return -99;
15282     }
15283
15284   if (vec_len (name) > 64)
15285     {
15286       errmsg ("profile name too long");
15287       return -99;
15288     }
15289
15290   M (IKEV2_INITIATE_SA_INIT, mp);
15291
15292   clib_memcpy (mp->name, name, vec_len (name));
15293   vec_free (name);
15294
15295   S (mp);
15296   W (ret);
15297   return ret;
15298 }
15299
15300 static int
15301 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15302 {
15303   unformat_input_t *i = vam->input;
15304   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15305   int ret;
15306   u64 ispi;
15307
15308
15309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15310     {
15311       if (unformat (i, "%lx", &ispi))
15312         ;
15313       else
15314         {
15315           errmsg ("parse error '%U'", format_unformat_error, i);
15316           return -99;
15317         }
15318     }
15319
15320   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15321
15322   mp->ispi = ispi;
15323
15324   S (mp);
15325   W (ret);
15326   return ret;
15327 }
15328
15329 static int
15330 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15331 {
15332   unformat_input_t *i = vam->input;
15333   vl_api_ikev2_initiate_del_child_sa_t *mp;
15334   int ret;
15335   u32 ispi;
15336
15337
15338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15339     {
15340       if (unformat (i, "%x", &ispi))
15341         ;
15342       else
15343         {
15344           errmsg ("parse error '%U'", format_unformat_error, i);
15345           return -99;
15346         }
15347     }
15348
15349   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15350
15351   mp->ispi = ispi;
15352
15353   S (mp);
15354   W (ret);
15355   return ret;
15356 }
15357
15358 static int
15359 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15360 {
15361   unformat_input_t *i = vam->input;
15362   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15363   int ret;
15364   u32 ispi;
15365
15366
15367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (i, "%x", &ispi))
15370         ;
15371       else
15372         {
15373           errmsg ("parse error '%U'", format_unformat_error, i);
15374           return -99;
15375         }
15376     }
15377
15378   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15379
15380   mp->ispi = ispi;
15381
15382   S (mp);
15383   W (ret);
15384   return ret;
15385 }
15386
15387 /*
15388  * MAP
15389  */
15390 static int
15391 api_map_add_domain (vat_main_t * vam)
15392 {
15393   unformat_input_t *i = vam->input;
15394   vl_api_map_add_domain_t *mp;
15395
15396   ip4_address_t ip4_prefix;
15397   ip6_address_t ip6_prefix;
15398   ip6_address_t ip6_src;
15399   u32 num_m_args = 0;
15400   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15401     0, psid_length = 0;
15402   u8 is_translation = 0;
15403   u32 mtu = 0;
15404   u32 ip6_src_len = 128;
15405   int ret;
15406
15407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15408     {
15409       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15410                     &ip4_prefix, &ip4_prefix_len))
15411         num_m_args++;
15412       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15413                          &ip6_prefix, &ip6_prefix_len))
15414         num_m_args++;
15415       else
15416         if (unformat
15417             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15418              &ip6_src_len))
15419         num_m_args++;
15420       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15421         num_m_args++;
15422       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15423         num_m_args++;
15424       else if (unformat (i, "psid-offset %d", &psid_offset))
15425         num_m_args++;
15426       else if (unformat (i, "psid-len %d", &psid_length))
15427         num_m_args++;
15428       else if (unformat (i, "mtu %d", &mtu))
15429         num_m_args++;
15430       else if (unformat (i, "map-t"))
15431         is_translation = 1;
15432       else
15433         {
15434           clib_warning ("parse error '%U'", format_unformat_error, i);
15435           return -99;
15436         }
15437     }
15438
15439   if (num_m_args < 3)
15440     {
15441       errmsg ("mandatory argument(s) missing");
15442       return -99;
15443     }
15444
15445   /* Construct the API message */
15446   M (MAP_ADD_DOMAIN, mp);
15447
15448   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15449   mp->ip4_prefix_len = ip4_prefix_len;
15450
15451   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15452   mp->ip6_prefix_len = ip6_prefix_len;
15453
15454   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15455   mp->ip6_src_prefix_len = ip6_src_len;
15456
15457   mp->ea_bits_len = ea_bits_len;
15458   mp->psid_offset = psid_offset;
15459   mp->psid_length = psid_length;
15460   mp->is_translation = is_translation;
15461   mp->mtu = htons (mtu);
15462
15463   /* send it... */
15464   S (mp);
15465
15466   /* Wait for a reply, return good/bad news  */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 static int
15472 api_map_del_domain (vat_main_t * vam)
15473 {
15474   unformat_input_t *i = vam->input;
15475   vl_api_map_del_domain_t *mp;
15476
15477   u32 num_m_args = 0;
15478   u32 index;
15479   int ret;
15480
15481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15482     {
15483       if (unformat (i, "index %d", &index))
15484         num_m_args++;
15485       else
15486         {
15487           clib_warning ("parse error '%U'", format_unformat_error, i);
15488           return -99;
15489         }
15490     }
15491
15492   if (num_m_args != 1)
15493     {
15494       errmsg ("mandatory argument(s) missing");
15495       return -99;
15496     }
15497
15498   /* Construct the API message */
15499   M (MAP_DEL_DOMAIN, mp);
15500
15501   mp->index = ntohl (index);
15502
15503   /* send it... */
15504   S (mp);
15505
15506   /* Wait for a reply, return good/bad news  */
15507   W (ret);
15508   return ret;
15509 }
15510
15511 static int
15512 api_map_add_del_rule (vat_main_t * vam)
15513 {
15514   unformat_input_t *i = vam->input;
15515   vl_api_map_add_del_rule_t *mp;
15516   u8 is_add = 1;
15517   ip6_address_t ip6_dst;
15518   u32 num_m_args = 0, index, psid = 0;
15519   int ret;
15520
15521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15522     {
15523       if (unformat (i, "index %d", &index))
15524         num_m_args++;
15525       else if (unformat (i, "psid %d", &psid))
15526         num_m_args++;
15527       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15528         num_m_args++;
15529       else if (unformat (i, "del"))
15530         {
15531           is_add = 0;
15532         }
15533       else
15534         {
15535           clib_warning ("parse error '%U'", format_unformat_error, i);
15536           return -99;
15537         }
15538     }
15539
15540   /* Construct the API message */
15541   M (MAP_ADD_DEL_RULE, mp);
15542
15543   mp->index = ntohl (index);
15544   mp->is_add = is_add;
15545   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15546   mp->psid = ntohs (psid);
15547
15548   /* send it... */
15549   S (mp);
15550
15551   /* Wait for a reply, return good/bad news  */
15552   W (ret);
15553   return ret;
15554 }
15555
15556 static int
15557 api_map_domain_dump (vat_main_t * vam)
15558 {
15559   vl_api_map_domain_dump_t *mp;
15560   vl_api_control_ping_t *mp_ping;
15561   int ret;
15562
15563   /* Construct the API message */
15564   M (MAP_DOMAIN_DUMP, mp);
15565
15566   /* send it... */
15567   S (mp);
15568
15569   /* Use a control ping for synchronization */
15570   MPING (CONTROL_PING, mp_ping);
15571   S (mp_ping);
15572
15573   W (ret);
15574   return ret;
15575 }
15576
15577 static int
15578 api_map_rule_dump (vat_main_t * vam)
15579 {
15580   unformat_input_t *i = vam->input;
15581   vl_api_map_rule_dump_t *mp;
15582   vl_api_control_ping_t *mp_ping;
15583   u32 domain_index = ~0;
15584   int ret;
15585
15586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (i, "index %u", &domain_index))
15589         ;
15590       else
15591         break;
15592     }
15593
15594   if (domain_index == ~0)
15595     {
15596       clib_warning ("parse error: domain index expected");
15597       return -99;
15598     }
15599
15600   /* Construct the API message */
15601   M (MAP_RULE_DUMP, mp);
15602
15603   mp->domain_index = htonl (domain_index);
15604
15605   /* send it... */
15606   S (mp);
15607
15608   /* Use a control ping for synchronization */
15609   MPING (CONTROL_PING, mp_ping);
15610   S (mp_ping);
15611
15612   W (ret);
15613   return ret;
15614 }
15615
15616 static void vl_api_map_add_domain_reply_t_handler
15617   (vl_api_map_add_domain_reply_t * mp)
15618 {
15619   vat_main_t *vam = &vat_main;
15620   i32 retval = ntohl (mp->retval);
15621
15622   if (vam->async_mode)
15623     {
15624       vam->async_errors += (retval < 0);
15625     }
15626   else
15627     {
15628       vam->retval = retval;
15629       vam->result_ready = 1;
15630     }
15631 }
15632
15633 static void vl_api_map_add_domain_reply_t_handler_json
15634   (vl_api_map_add_domain_reply_t * mp)
15635 {
15636   vat_main_t *vam = &vat_main;
15637   vat_json_node_t node;
15638
15639   vat_json_init_object (&node);
15640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15641   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15642
15643   vat_json_print (vam->ofp, &node);
15644   vat_json_free (&node);
15645
15646   vam->retval = ntohl (mp->retval);
15647   vam->result_ready = 1;
15648 }
15649
15650 static int
15651 api_get_first_msg_id (vat_main_t * vam)
15652 {
15653   vl_api_get_first_msg_id_t *mp;
15654   unformat_input_t *i = vam->input;
15655   u8 *name;
15656   u8 name_set = 0;
15657   int ret;
15658
15659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15660     {
15661       if (unformat (i, "client %s", &name))
15662         name_set = 1;
15663       else
15664         break;
15665     }
15666
15667   if (name_set == 0)
15668     {
15669       errmsg ("missing client name");
15670       return -99;
15671     }
15672   vec_add1 (name, 0);
15673
15674   if (vec_len (name) > 63)
15675     {
15676       errmsg ("client name too long");
15677       return -99;
15678     }
15679
15680   M (GET_FIRST_MSG_ID, mp);
15681   clib_memcpy (mp->name, name, vec_len (name));
15682   S (mp);
15683   W (ret);
15684   return ret;
15685 }
15686
15687 static int
15688 api_cop_interface_enable_disable (vat_main_t * vam)
15689 {
15690   unformat_input_t *line_input = vam->input;
15691   vl_api_cop_interface_enable_disable_t *mp;
15692   u32 sw_if_index = ~0;
15693   u8 enable_disable = 1;
15694   int ret;
15695
15696   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15697     {
15698       if (unformat (line_input, "disable"))
15699         enable_disable = 0;
15700       if (unformat (line_input, "enable"))
15701         enable_disable = 1;
15702       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15703                          vam, &sw_if_index))
15704         ;
15705       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15706         ;
15707       else
15708         break;
15709     }
15710
15711   if (sw_if_index == ~0)
15712     {
15713       errmsg ("missing interface name or sw_if_index");
15714       return -99;
15715     }
15716
15717   /* Construct the API message */
15718   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15719   mp->sw_if_index = ntohl (sw_if_index);
15720   mp->enable_disable = enable_disable;
15721
15722   /* send it... */
15723   S (mp);
15724   /* Wait for the reply */
15725   W (ret);
15726   return ret;
15727 }
15728
15729 static int
15730 api_cop_whitelist_enable_disable (vat_main_t * vam)
15731 {
15732   unformat_input_t *line_input = vam->input;
15733   vl_api_cop_whitelist_enable_disable_t *mp;
15734   u32 sw_if_index = ~0;
15735   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15736   u32 fib_id = 0;
15737   int ret;
15738
15739   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15740     {
15741       if (unformat (line_input, "ip4"))
15742         ip4 = 1;
15743       else if (unformat (line_input, "ip6"))
15744         ip6 = 1;
15745       else if (unformat (line_input, "default"))
15746         default_cop = 1;
15747       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15748                          vam, &sw_if_index))
15749         ;
15750       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15751         ;
15752       else if (unformat (line_input, "fib-id %d", &fib_id))
15753         ;
15754       else
15755         break;
15756     }
15757
15758   if (sw_if_index == ~0)
15759     {
15760       errmsg ("missing interface name or sw_if_index");
15761       return -99;
15762     }
15763
15764   /* Construct the API message */
15765   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15766   mp->sw_if_index = ntohl (sw_if_index);
15767   mp->fib_id = ntohl (fib_id);
15768   mp->ip4 = ip4;
15769   mp->ip6 = ip6;
15770   mp->default_cop = default_cop;
15771
15772   /* send it... */
15773   S (mp);
15774   /* Wait for the reply */
15775   W (ret);
15776   return ret;
15777 }
15778
15779 static int
15780 api_get_node_graph (vat_main_t * vam)
15781 {
15782   vl_api_get_node_graph_t *mp;
15783   int ret;
15784
15785   M (GET_NODE_GRAPH, mp);
15786
15787   /* send it... */
15788   S (mp);
15789   /* Wait for the reply */
15790   W (ret);
15791   return ret;
15792 }
15793
15794 /* *INDENT-OFF* */
15795 /** Used for parsing LISP eids */
15796 typedef CLIB_PACKED(struct{
15797   u8 addr[16];   /**< eid address */
15798   u32 len;       /**< prefix length if IP */
15799   u8 type;      /**< type of eid */
15800 }) lisp_eid_vat_t;
15801 /* *INDENT-ON* */
15802
15803 static uword
15804 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15805 {
15806   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15807
15808   memset (a, 0, sizeof (a[0]));
15809
15810   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15811     {
15812       a->type = 0;              /* ipv4 type */
15813     }
15814   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15815     {
15816       a->type = 1;              /* ipv6 type */
15817     }
15818   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15819     {
15820       a->type = 2;              /* mac type */
15821     }
15822   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15823     {
15824       a->type = 3;              /* NSH type */
15825       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15826       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15827     }
15828   else
15829     {
15830       return 0;
15831     }
15832
15833   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15834     {
15835       return 0;
15836     }
15837
15838   return 1;
15839 }
15840
15841 static int
15842 lisp_eid_size_vat (u8 type)
15843 {
15844   switch (type)
15845     {
15846     case 0:
15847       return 4;
15848     case 1:
15849       return 16;
15850     case 2:
15851       return 6;
15852     case 3:
15853       return 5;
15854     }
15855   return 0;
15856 }
15857
15858 static void
15859 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15860 {
15861   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15862 }
15863
15864 static int
15865 api_one_add_del_locator_set (vat_main_t * vam)
15866 {
15867   unformat_input_t *input = vam->input;
15868   vl_api_one_add_del_locator_set_t *mp;
15869   u8 is_add = 1;
15870   u8 *locator_set_name = NULL;
15871   u8 locator_set_name_set = 0;
15872   vl_api_local_locator_t locator, *locators = 0;
15873   u32 sw_if_index, priority, weight;
15874   u32 data_len = 0;
15875
15876   int ret;
15877   /* Parse args required to build the message */
15878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15879     {
15880       if (unformat (input, "del"))
15881         {
15882           is_add = 0;
15883         }
15884       else if (unformat (input, "locator-set %s", &locator_set_name))
15885         {
15886           locator_set_name_set = 1;
15887         }
15888       else if (unformat (input, "sw_if_index %u p %u w %u",
15889                          &sw_if_index, &priority, &weight))
15890         {
15891           locator.sw_if_index = htonl (sw_if_index);
15892           locator.priority = priority;
15893           locator.weight = weight;
15894           vec_add1 (locators, locator);
15895         }
15896       else
15897         if (unformat
15898             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15899              &sw_if_index, &priority, &weight))
15900         {
15901           locator.sw_if_index = htonl (sw_if_index);
15902           locator.priority = priority;
15903           locator.weight = weight;
15904           vec_add1 (locators, locator);
15905         }
15906       else
15907         break;
15908     }
15909
15910   if (locator_set_name_set == 0)
15911     {
15912       errmsg ("missing locator-set name");
15913       vec_free (locators);
15914       return -99;
15915     }
15916
15917   if (vec_len (locator_set_name) > 64)
15918     {
15919       errmsg ("locator-set name too long");
15920       vec_free (locator_set_name);
15921       vec_free (locators);
15922       return -99;
15923     }
15924   vec_add1 (locator_set_name, 0);
15925
15926   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15927
15928   /* Construct the API message */
15929   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15930
15931   mp->is_add = is_add;
15932   clib_memcpy (mp->locator_set_name, locator_set_name,
15933                vec_len (locator_set_name));
15934   vec_free (locator_set_name);
15935
15936   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15937   if (locators)
15938     clib_memcpy (mp->locators, locators, data_len);
15939   vec_free (locators);
15940
15941   /* send it... */
15942   S (mp);
15943
15944   /* Wait for a reply... */
15945   W (ret);
15946   return ret;
15947 }
15948
15949 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15950
15951 static int
15952 api_one_add_del_locator (vat_main_t * vam)
15953 {
15954   unformat_input_t *input = vam->input;
15955   vl_api_one_add_del_locator_t *mp;
15956   u32 tmp_if_index = ~0;
15957   u32 sw_if_index = ~0;
15958   u8 sw_if_index_set = 0;
15959   u8 sw_if_index_if_name_set = 0;
15960   u32 priority = ~0;
15961   u8 priority_set = 0;
15962   u32 weight = ~0;
15963   u8 weight_set = 0;
15964   u8 is_add = 1;
15965   u8 *locator_set_name = NULL;
15966   u8 locator_set_name_set = 0;
15967   int ret;
15968
15969   /* Parse args required to build the message */
15970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15971     {
15972       if (unformat (input, "del"))
15973         {
15974           is_add = 0;
15975         }
15976       else if (unformat (input, "locator-set %s", &locator_set_name))
15977         {
15978           locator_set_name_set = 1;
15979         }
15980       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15981                          &tmp_if_index))
15982         {
15983           sw_if_index_if_name_set = 1;
15984           sw_if_index = tmp_if_index;
15985         }
15986       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15987         {
15988           sw_if_index_set = 1;
15989           sw_if_index = tmp_if_index;
15990         }
15991       else if (unformat (input, "p %d", &priority))
15992         {
15993           priority_set = 1;
15994         }
15995       else if (unformat (input, "w %d", &weight))
15996         {
15997           weight_set = 1;
15998         }
15999       else
16000         break;
16001     }
16002
16003   if (locator_set_name_set == 0)
16004     {
16005       errmsg ("missing locator-set name");
16006       return -99;
16007     }
16008
16009   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16010     {
16011       errmsg ("missing sw_if_index");
16012       vec_free (locator_set_name);
16013       return -99;
16014     }
16015
16016   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16017     {
16018       errmsg ("cannot use both params interface name and sw_if_index");
16019       vec_free (locator_set_name);
16020       return -99;
16021     }
16022
16023   if (priority_set == 0)
16024     {
16025       errmsg ("missing locator-set priority");
16026       vec_free (locator_set_name);
16027       return -99;
16028     }
16029
16030   if (weight_set == 0)
16031     {
16032       errmsg ("missing locator-set weight");
16033       vec_free (locator_set_name);
16034       return -99;
16035     }
16036
16037   if (vec_len (locator_set_name) > 64)
16038     {
16039       errmsg ("locator-set name too long");
16040       vec_free (locator_set_name);
16041       return -99;
16042     }
16043   vec_add1 (locator_set_name, 0);
16044
16045   /* Construct the API message */
16046   M (ONE_ADD_DEL_LOCATOR, mp);
16047
16048   mp->is_add = is_add;
16049   mp->sw_if_index = ntohl (sw_if_index);
16050   mp->priority = priority;
16051   mp->weight = weight;
16052   clib_memcpy (mp->locator_set_name, locator_set_name,
16053                vec_len (locator_set_name));
16054   vec_free (locator_set_name);
16055
16056   /* send it... */
16057   S (mp);
16058
16059   /* Wait for a reply... */
16060   W (ret);
16061   return ret;
16062 }
16063
16064 #define api_lisp_add_del_locator api_one_add_del_locator
16065
16066 uword
16067 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16068 {
16069   u32 *key_id = va_arg (*args, u32 *);
16070   u8 *s = 0;
16071
16072   if (unformat (input, "%s", &s))
16073     {
16074       if (!strcmp ((char *) s, "sha1"))
16075         key_id[0] = HMAC_SHA_1_96;
16076       else if (!strcmp ((char *) s, "sha256"))
16077         key_id[0] = HMAC_SHA_256_128;
16078       else
16079         {
16080           clib_warning ("invalid key_id: '%s'", s);
16081           key_id[0] = HMAC_NO_KEY;
16082         }
16083     }
16084   else
16085     return 0;
16086
16087   vec_free (s);
16088   return 1;
16089 }
16090
16091 static int
16092 api_one_add_del_local_eid (vat_main_t * vam)
16093 {
16094   unformat_input_t *input = vam->input;
16095   vl_api_one_add_del_local_eid_t *mp;
16096   u8 is_add = 1;
16097   u8 eid_set = 0;
16098   lisp_eid_vat_t _eid, *eid = &_eid;
16099   u8 *locator_set_name = 0;
16100   u8 locator_set_name_set = 0;
16101   u32 vni = 0;
16102   u16 key_id = 0;
16103   u8 *key = 0;
16104   int ret;
16105
16106   /* Parse args required to build the message */
16107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16108     {
16109       if (unformat (input, "del"))
16110         {
16111           is_add = 0;
16112         }
16113       else if (unformat (input, "vni %d", &vni))
16114         {
16115           ;
16116         }
16117       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16118         {
16119           eid_set = 1;
16120         }
16121       else if (unformat (input, "locator-set %s", &locator_set_name))
16122         {
16123           locator_set_name_set = 1;
16124         }
16125       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16126         ;
16127       else if (unformat (input, "secret-key %_%v%_", &key))
16128         ;
16129       else
16130         break;
16131     }
16132
16133   if (locator_set_name_set == 0)
16134     {
16135       errmsg ("missing locator-set name");
16136       return -99;
16137     }
16138
16139   if (0 == eid_set)
16140     {
16141       errmsg ("EID address not set!");
16142       vec_free (locator_set_name);
16143       return -99;
16144     }
16145
16146   if (key && (0 == key_id))
16147     {
16148       errmsg ("invalid key_id!");
16149       return -99;
16150     }
16151
16152   if (vec_len (key) > 64)
16153     {
16154       errmsg ("key too long");
16155       vec_free (key);
16156       return -99;
16157     }
16158
16159   if (vec_len (locator_set_name) > 64)
16160     {
16161       errmsg ("locator-set name too long");
16162       vec_free (locator_set_name);
16163       return -99;
16164     }
16165   vec_add1 (locator_set_name, 0);
16166
16167   /* Construct the API message */
16168   M (ONE_ADD_DEL_LOCAL_EID, mp);
16169
16170   mp->is_add = is_add;
16171   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16172   mp->eid_type = eid->type;
16173   mp->prefix_len = eid->len;
16174   mp->vni = clib_host_to_net_u32 (vni);
16175   mp->key_id = clib_host_to_net_u16 (key_id);
16176   clib_memcpy (mp->locator_set_name, locator_set_name,
16177                vec_len (locator_set_name));
16178   clib_memcpy (mp->key, key, vec_len (key));
16179
16180   vec_free (locator_set_name);
16181   vec_free (key);
16182
16183   /* send it... */
16184   S (mp);
16185
16186   /* Wait for a reply... */
16187   W (ret);
16188   return ret;
16189 }
16190
16191 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16192
16193 static int
16194 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16195 {
16196   u32 dp_table = 0, vni = 0;;
16197   unformat_input_t *input = vam->input;
16198   vl_api_gpe_add_del_fwd_entry_t *mp;
16199   u8 is_add = 1;
16200   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16201   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16202   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16203   u32 action = ~0, w;
16204   ip4_address_t rmt_rloc4, lcl_rloc4;
16205   ip6_address_t rmt_rloc6, lcl_rloc6;
16206   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16207   int ret;
16208
16209   memset (&rloc, 0, sizeof (rloc));
16210
16211   /* Parse args required to build the message */
16212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (input, "del"))
16215         is_add = 0;
16216       else if (unformat (input, "add"))
16217         is_add = 1;
16218       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16219         {
16220           rmt_eid_set = 1;
16221         }
16222       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16223         {
16224           lcl_eid_set = 1;
16225         }
16226       else if (unformat (input, "vrf %d", &dp_table))
16227         ;
16228       else if (unformat (input, "bd %d", &dp_table))
16229         ;
16230       else if (unformat (input, "vni %d", &vni))
16231         ;
16232       else if (unformat (input, "w %d", &w))
16233         {
16234           if (!curr_rloc)
16235             {
16236               errmsg ("No RLOC configured for setting priority/weight!");
16237               return -99;
16238             }
16239           curr_rloc->weight = w;
16240         }
16241       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16242                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16243         {
16244           rloc.is_ip4 = 1;
16245
16246           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16247           rloc.weight = 0;
16248           vec_add1 (lcl_locs, rloc);
16249
16250           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16251           vec_add1 (rmt_locs, rloc);
16252           /* weight saved in rmt loc */
16253           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16254         }
16255       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16256                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16257         {
16258           rloc.is_ip4 = 0;
16259           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16260           rloc.weight = 0;
16261           vec_add1 (lcl_locs, rloc);
16262
16263           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16264           vec_add1 (rmt_locs, rloc);
16265           /* weight saved in rmt loc */
16266           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16267         }
16268       else if (unformat (input, "action %d", &action))
16269         {
16270           ;
16271         }
16272       else
16273         {
16274           clib_warning ("parse error '%U'", format_unformat_error, input);
16275           return -99;
16276         }
16277     }
16278
16279   if (!rmt_eid_set)
16280     {
16281       errmsg ("remote eid addresses not set");
16282       return -99;
16283     }
16284
16285   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16286     {
16287       errmsg ("eid types don't match");
16288       return -99;
16289     }
16290
16291   if (0 == rmt_locs && (u32) ~ 0 == action)
16292     {
16293       errmsg ("action not set for negative mapping");
16294       return -99;
16295     }
16296
16297   /* Construct the API message */
16298   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16299       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16300
16301   mp->is_add = is_add;
16302   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16303   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16304   mp->eid_type = rmt_eid->type;
16305   mp->dp_table = clib_host_to_net_u32 (dp_table);
16306   mp->vni = clib_host_to_net_u32 (vni);
16307   mp->rmt_len = rmt_eid->len;
16308   mp->lcl_len = lcl_eid->len;
16309   mp->action = action;
16310
16311   if (0 != rmt_locs && 0 != lcl_locs)
16312     {
16313       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16314       clib_memcpy (mp->locs, lcl_locs,
16315                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16316
16317       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16318       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16319                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16320     }
16321   vec_free (lcl_locs);
16322   vec_free (rmt_locs);
16323
16324   /* send it... */
16325   S (mp);
16326
16327   /* Wait for a reply... */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 static int
16333 api_one_add_del_map_server (vat_main_t * vam)
16334 {
16335   unformat_input_t *input = vam->input;
16336   vl_api_one_add_del_map_server_t *mp;
16337   u8 is_add = 1;
16338   u8 ipv4_set = 0;
16339   u8 ipv6_set = 0;
16340   ip4_address_t ipv4;
16341   ip6_address_t ipv6;
16342   int ret;
16343
16344   /* Parse args required to build the message */
16345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16346     {
16347       if (unformat (input, "del"))
16348         {
16349           is_add = 0;
16350         }
16351       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16352         {
16353           ipv4_set = 1;
16354         }
16355       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16356         {
16357           ipv6_set = 1;
16358         }
16359       else
16360         break;
16361     }
16362
16363   if (ipv4_set && ipv6_set)
16364     {
16365       errmsg ("both eid v4 and v6 addresses set");
16366       return -99;
16367     }
16368
16369   if (!ipv4_set && !ipv6_set)
16370     {
16371       errmsg ("eid addresses not set");
16372       return -99;
16373     }
16374
16375   /* Construct the API message */
16376   M (ONE_ADD_DEL_MAP_SERVER, mp);
16377
16378   mp->is_add = is_add;
16379   if (ipv6_set)
16380     {
16381       mp->is_ipv6 = 1;
16382       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16383     }
16384   else
16385     {
16386       mp->is_ipv6 = 0;
16387       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16388     }
16389
16390   /* send it... */
16391   S (mp);
16392
16393   /* Wait for a reply... */
16394   W (ret);
16395   return ret;
16396 }
16397
16398 #define api_lisp_add_del_map_server api_one_add_del_map_server
16399
16400 static int
16401 api_one_add_del_map_resolver (vat_main_t * vam)
16402 {
16403   unformat_input_t *input = vam->input;
16404   vl_api_one_add_del_map_resolver_t *mp;
16405   u8 is_add = 1;
16406   u8 ipv4_set = 0;
16407   u8 ipv6_set = 0;
16408   ip4_address_t ipv4;
16409   ip6_address_t ipv6;
16410   int ret;
16411
16412   /* Parse args required to build the message */
16413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (input, "del"))
16416         {
16417           is_add = 0;
16418         }
16419       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16420         {
16421           ipv4_set = 1;
16422         }
16423       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16424         {
16425           ipv6_set = 1;
16426         }
16427       else
16428         break;
16429     }
16430
16431   if (ipv4_set && ipv6_set)
16432     {
16433       errmsg ("both eid v4 and v6 addresses set");
16434       return -99;
16435     }
16436
16437   if (!ipv4_set && !ipv6_set)
16438     {
16439       errmsg ("eid addresses not set");
16440       return -99;
16441     }
16442
16443   /* Construct the API message */
16444   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16445
16446   mp->is_add = is_add;
16447   if (ipv6_set)
16448     {
16449       mp->is_ipv6 = 1;
16450       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16451     }
16452   else
16453     {
16454       mp->is_ipv6 = 0;
16455       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16456     }
16457
16458   /* send it... */
16459   S (mp);
16460
16461   /* Wait for a reply... */
16462   W (ret);
16463   return ret;
16464 }
16465
16466 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16467
16468 static int
16469 api_lisp_gpe_enable_disable (vat_main_t * vam)
16470 {
16471   unformat_input_t *input = vam->input;
16472   vl_api_gpe_enable_disable_t *mp;
16473   u8 is_set = 0;
16474   u8 is_en = 1;
16475   int ret;
16476
16477   /* Parse args required to build the message */
16478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16479     {
16480       if (unformat (input, "enable"))
16481         {
16482           is_set = 1;
16483           is_en = 1;
16484         }
16485       else if (unformat (input, "disable"))
16486         {
16487           is_set = 1;
16488           is_en = 0;
16489         }
16490       else
16491         break;
16492     }
16493
16494   if (is_set == 0)
16495     {
16496       errmsg ("Value not set");
16497       return -99;
16498     }
16499
16500   /* Construct the API message */
16501   M (GPE_ENABLE_DISABLE, mp);
16502
16503   mp->is_en = is_en;
16504
16505   /* send it... */
16506   S (mp);
16507
16508   /* Wait for a reply... */
16509   W (ret);
16510   return ret;
16511 }
16512
16513 static int
16514 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16515 {
16516   unformat_input_t *input = vam->input;
16517   vl_api_one_rloc_probe_enable_disable_t *mp;
16518   u8 is_set = 0;
16519   u8 is_en = 0;
16520   int ret;
16521
16522   /* Parse args required to build the message */
16523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16524     {
16525       if (unformat (input, "enable"))
16526         {
16527           is_set = 1;
16528           is_en = 1;
16529         }
16530       else if (unformat (input, "disable"))
16531         is_set = 1;
16532       else
16533         break;
16534     }
16535
16536   if (!is_set)
16537     {
16538       errmsg ("Value not set");
16539       return -99;
16540     }
16541
16542   /* Construct the API message */
16543   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16544
16545   mp->is_enabled = is_en;
16546
16547   /* send it... */
16548   S (mp);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16556
16557 static int
16558 api_one_map_register_enable_disable (vat_main_t * vam)
16559 {
16560   unformat_input_t *input = vam->input;
16561   vl_api_one_map_register_enable_disable_t *mp;
16562   u8 is_set = 0;
16563   u8 is_en = 0;
16564   int ret;
16565
16566   /* Parse args required to build the message */
16567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16568     {
16569       if (unformat (input, "enable"))
16570         {
16571           is_set = 1;
16572           is_en = 1;
16573         }
16574       else if (unformat (input, "disable"))
16575         is_set = 1;
16576       else
16577         break;
16578     }
16579
16580   if (!is_set)
16581     {
16582       errmsg ("Value not set");
16583       return -99;
16584     }
16585
16586   /* Construct the API message */
16587   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16588
16589   mp->is_enabled = is_en;
16590
16591   /* send it... */
16592   S (mp);
16593
16594   /* Wait for a reply... */
16595   W (ret);
16596   return ret;
16597 }
16598
16599 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16600
16601 static int
16602 api_one_enable_disable (vat_main_t * vam)
16603 {
16604   unformat_input_t *input = vam->input;
16605   vl_api_one_enable_disable_t *mp;
16606   u8 is_set = 0;
16607   u8 is_en = 0;
16608   int ret;
16609
16610   /* Parse args required to build the message */
16611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16612     {
16613       if (unformat (input, "enable"))
16614         {
16615           is_set = 1;
16616           is_en = 1;
16617         }
16618       else if (unformat (input, "disable"))
16619         {
16620           is_set = 1;
16621         }
16622       else
16623         break;
16624     }
16625
16626   if (!is_set)
16627     {
16628       errmsg ("Value not set");
16629       return -99;
16630     }
16631
16632   /* Construct the API message */
16633   M (ONE_ENABLE_DISABLE, mp);
16634
16635   mp->is_en = is_en;
16636
16637   /* send it... */
16638   S (mp);
16639
16640   /* Wait for a reply... */
16641   W (ret);
16642   return ret;
16643 }
16644
16645 #define api_lisp_enable_disable api_one_enable_disable
16646
16647 static int
16648 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16649 {
16650   unformat_input_t *input = vam->input;
16651   vl_api_one_enable_disable_xtr_mode_t *mp;
16652   u8 is_set = 0;
16653   u8 is_en = 0;
16654   int ret;
16655
16656   /* Parse args required to build the message */
16657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16658     {
16659       if (unformat (input, "enable"))
16660         {
16661           is_set = 1;
16662           is_en = 1;
16663         }
16664       else if (unformat (input, "disable"))
16665         {
16666           is_set = 1;
16667         }
16668       else
16669         break;
16670     }
16671
16672   if (!is_set)
16673     {
16674       errmsg ("Value not set");
16675       return -99;
16676     }
16677
16678   /* Construct the API message */
16679   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16680
16681   mp->is_en = is_en;
16682
16683   /* send it... */
16684   S (mp);
16685
16686   /* Wait for a reply... */
16687   W (ret);
16688   return ret;
16689 }
16690
16691 static int
16692 api_one_show_xtr_mode (vat_main_t * vam)
16693 {
16694   vl_api_one_show_xtr_mode_t *mp;
16695   int ret;
16696
16697   /* Construct the API message */
16698   M (ONE_SHOW_XTR_MODE, mp);
16699
16700   /* send it... */
16701   S (mp);
16702
16703   /* Wait for a reply... */
16704   W (ret);
16705   return ret;
16706 }
16707
16708 static int
16709 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16710 {
16711   unformat_input_t *input = vam->input;
16712   vl_api_one_enable_disable_pitr_mode_t *mp;
16713   u8 is_set = 0;
16714   u8 is_en = 0;
16715   int ret;
16716
16717   /* Parse args required to build the message */
16718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16719     {
16720       if (unformat (input, "enable"))
16721         {
16722           is_set = 1;
16723           is_en = 1;
16724         }
16725       else if (unformat (input, "disable"))
16726         {
16727           is_set = 1;
16728         }
16729       else
16730         break;
16731     }
16732
16733   if (!is_set)
16734     {
16735       errmsg ("Value not set");
16736       return -99;
16737     }
16738
16739   /* Construct the API message */
16740   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16741
16742   mp->is_en = is_en;
16743
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 static int
16753 api_one_show_pitr_mode (vat_main_t * vam)
16754 {
16755   vl_api_one_show_pitr_mode_t *mp;
16756   int ret;
16757
16758   /* Construct the API message */
16759   M (ONE_SHOW_PITR_MODE, mp);
16760
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 static int
16770 api_one_enable_disable_petr_mode (vat_main_t * vam)
16771 {
16772   unformat_input_t *input = vam->input;
16773   vl_api_one_enable_disable_petr_mode_t *mp;
16774   u8 is_set = 0;
16775   u8 is_en = 0;
16776   int ret;
16777
16778   /* Parse args required to build the message */
16779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16780     {
16781       if (unformat (input, "enable"))
16782         {
16783           is_set = 1;
16784           is_en = 1;
16785         }
16786       else if (unformat (input, "disable"))
16787         {
16788           is_set = 1;
16789         }
16790       else
16791         break;
16792     }
16793
16794   if (!is_set)
16795     {
16796       errmsg ("Value not set");
16797       return -99;
16798     }
16799
16800   /* Construct the API message */
16801   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16802
16803   mp->is_en = is_en;
16804
16805   /* send it... */
16806   S (mp);
16807
16808   /* Wait for a reply... */
16809   W (ret);
16810   return ret;
16811 }
16812
16813 static int
16814 api_one_show_petr_mode (vat_main_t * vam)
16815 {
16816   vl_api_one_show_petr_mode_t *mp;
16817   int ret;
16818
16819   /* Construct the API message */
16820   M (ONE_SHOW_PETR_MODE, mp);
16821
16822   /* send it... */
16823   S (mp);
16824
16825   /* Wait for a reply... */
16826   W (ret);
16827   return ret;
16828 }
16829
16830 static int
16831 api_show_one_map_register_state (vat_main_t * vam)
16832 {
16833   vl_api_show_one_map_register_state_t *mp;
16834   int ret;
16835
16836   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16837
16838   /* send */
16839   S (mp);
16840
16841   /* wait for reply */
16842   W (ret);
16843   return ret;
16844 }
16845
16846 #define api_show_lisp_map_register_state api_show_one_map_register_state
16847
16848 static int
16849 api_show_one_rloc_probe_state (vat_main_t * vam)
16850 {
16851   vl_api_show_one_rloc_probe_state_t *mp;
16852   int ret;
16853
16854   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16855
16856   /* send */
16857   S (mp);
16858
16859   /* wait for reply */
16860   W (ret);
16861   return ret;
16862 }
16863
16864 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16865
16866 static int
16867 api_one_add_del_ndp_entry (vat_main_t * vam)
16868 {
16869   vl_api_one_add_del_ndp_entry_t *mp;
16870   unformat_input_t *input = vam->input;
16871   u8 is_add = 1;
16872   u8 mac_set = 0;
16873   u8 bd_set = 0;
16874   u8 ip_set = 0;
16875   u8 mac[6] = { 0, };
16876   u8 ip6[16] = { 0, };
16877   u32 bd = ~0;
16878   int ret;
16879
16880   /* Parse args required to build the message */
16881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16882     {
16883       if (unformat (input, "del"))
16884         is_add = 0;
16885       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16886         mac_set = 1;
16887       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16888         ip_set = 1;
16889       else if (unformat (input, "bd %d", &bd))
16890         bd_set = 1;
16891       else
16892         {
16893           errmsg ("parse error '%U'", format_unformat_error, input);
16894           return -99;
16895         }
16896     }
16897
16898   if (!bd_set || !ip_set || (!mac_set && is_add))
16899     {
16900       errmsg ("Missing BD, IP or MAC!");
16901       return -99;
16902     }
16903
16904   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16905   mp->is_add = is_add;
16906   clib_memcpy (mp->mac, mac, 6);
16907   mp->bd = clib_host_to_net_u32 (bd);
16908   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16909
16910   /* send */
16911   S (mp);
16912
16913   /* wait for reply */
16914   W (ret);
16915   return ret;
16916 }
16917
16918 static int
16919 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16920 {
16921   vl_api_one_add_del_l2_arp_entry_t *mp;
16922   unformat_input_t *input = vam->input;
16923   u8 is_add = 1;
16924   u8 mac_set = 0;
16925   u8 bd_set = 0;
16926   u8 ip_set = 0;
16927   u8 mac[6] = { 0, };
16928   u32 ip4 = 0, bd = ~0;
16929   int ret;
16930
16931   /* Parse args required to build the message */
16932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16933     {
16934       if (unformat (input, "del"))
16935         is_add = 0;
16936       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16937         mac_set = 1;
16938       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16939         ip_set = 1;
16940       else if (unformat (input, "bd %d", &bd))
16941         bd_set = 1;
16942       else
16943         {
16944           errmsg ("parse error '%U'", format_unformat_error, input);
16945           return -99;
16946         }
16947     }
16948
16949   if (!bd_set || !ip_set || (!mac_set && is_add))
16950     {
16951       errmsg ("Missing BD, IP or MAC!");
16952       return -99;
16953     }
16954
16955   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16956   mp->is_add = is_add;
16957   clib_memcpy (mp->mac, mac, 6);
16958   mp->bd = clib_host_to_net_u32 (bd);
16959   mp->ip4 = ip4;
16960
16961   /* send */
16962   S (mp);
16963
16964   /* wait for reply */
16965   W (ret);
16966   return ret;
16967 }
16968
16969 static int
16970 api_one_ndp_bd_get (vat_main_t * vam)
16971 {
16972   vl_api_one_ndp_bd_get_t *mp;
16973   int ret;
16974
16975   M (ONE_NDP_BD_GET, mp);
16976
16977   /* send */
16978   S (mp);
16979
16980   /* wait for reply */
16981   W (ret);
16982   return ret;
16983 }
16984
16985 static int
16986 api_one_ndp_entries_get (vat_main_t * vam)
16987 {
16988   vl_api_one_ndp_entries_get_t *mp;
16989   unformat_input_t *input = vam->input;
16990   u8 bd_set = 0;
16991   u32 bd = ~0;
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, "bd %d", &bd))
16998         bd_set = 1;
16999       else
17000         {
17001           errmsg ("parse error '%U'", format_unformat_error, input);
17002           return -99;
17003         }
17004     }
17005
17006   if (!bd_set)
17007     {
17008       errmsg ("Expected bridge domain!");
17009       return -99;
17010     }
17011
17012   M (ONE_NDP_ENTRIES_GET, mp);
17013   mp->bd = clib_host_to_net_u32 (bd);
17014
17015   /* send */
17016   S (mp);
17017
17018   /* wait for reply */
17019   W (ret);
17020   return ret;
17021 }
17022
17023 static int
17024 api_one_l2_arp_bd_get (vat_main_t * vam)
17025 {
17026   vl_api_one_l2_arp_bd_get_t *mp;
17027   int ret;
17028
17029   M (ONE_L2_ARP_BD_GET, mp);
17030
17031   /* send */
17032   S (mp);
17033
17034   /* wait for reply */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 static int
17040 api_one_l2_arp_entries_get (vat_main_t * vam)
17041 {
17042   vl_api_one_l2_arp_entries_get_t *mp;
17043   unformat_input_t *input = vam->input;
17044   u8 bd_set = 0;
17045   u32 bd = ~0;
17046   int ret;
17047
17048   /* Parse args required to build the message */
17049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17050     {
17051       if (unformat (input, "bd %d", &bd))
17052         bd_set = 1;
17053       else
17054         {
17055           errmsg ("parse error '%U'", format_unformat_error, input);
17056           return -99;
17057         }
17058     }
17059
17060   if (!bd_set)
17061     {
17062       errmsg ("Expected bridge domain!");
17063       return -99;
17064     }
17065
17066   M (ONE_L2_ARP_ENTRIES_GET, mp);
17067   mp->bd = clib_host_to_net_u32 (bd);
17068
17069   /* send */
17070   S (mp);
17071
17072   /* wait for reply */
17073   W (ret);
17074   return ret;
17075 }
17076
17077 static int
17078 api_one_stats_enable_disable (vat_main_t * vam)
17079 {
17080   vl_api_one_stats_enable_disable_t *mp;
17081   unformat_input_t *input = vam->input;
17082   u8 is_set = 0;
17083   u8 is_en = 0;
17084   int ret;
17085
17086   /* Parse args required to build the message */
17087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (input, "enable"))
17090         {
17091           is_set = 1;
17092           is_en = 1;
17093         }
17094       else if (unformat (input, "disable"))
17095         {
17096           is_set = 1;
17097         }
17098       else
17099         break;
17100     }
17101
17102   if (!is_set)
17103     {
17104       errmsg ("Value not set");
17105       return -99;
17106     }
17107
17108   M (ONE_STATS_ENABLE_DISABLE, mp);
17109   mp->is_en = is_en;
17110
17111   /* send */
17112   S (mp);
17113
17114   /* wait for reply */
17115   W (ret);
17116   return ret;
17117 }
17118
17119 static int
17120 api_show_one_stats_enable_disable (vat_main_t * vam)
17121 {
17122   vl_api_show_one_stats_enable_disable_t *mp;
17123   int ret;
17124
17125   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17126
17127   /* send */
17128   S (mp);
17129
17130   /* wait for reply */
17131   W (ret);
17132   return ret;
17133 }
17134
17135 static int
17136 api_show_one_map_request_mode (vat_main_t * vam)
17137 {
17138   vl_api_show_one_map_request_mode_t *mp;
17139   int ret;
17140
17141   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17142
17143   /* send */
17144   S (mp);
17145
17146   /* wait for reply */
17147   W (ret);
17148   return ret;
17149 }
17150
17151 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17152
17153 static int
17154 api_one_map_request_mode (vat_main_t * vam)
17155 {
17156   unformat_input_t *input = vam->input;
17157   vl_api_one_map_request_mode_t *mp;
17158   u8 mode = 0;
17159   int ret;
17160
17161   /* Parse args required to build the message */
17162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17163     {
17164       if (unformat (input, "dst-only"))
17165         mode = 0;
17166       else if (unformat (input, "src-dst"))
17167         mode = 1;
17168       else
17169         {
17170           errmsg ("parse error '%U'", format_unformat_error, input);
17171           return -99;
17172         }
17173     }
17174
17175   M (ONE_MAP_REQUEST_MODE, mp);
17176
17177   mp->mode = mode;
17178
17179   /* send */
17180   S (mp);
17181
17182   /* wait for reply */
17183   W (ret);
17184   return ret;
17185 }
17186
17187 #define api_lisp_map_request_mode api_one_map_request_mode
17188
17189 /**
17190  * Enable/disable ONE proxy ITR.
17191  *
17192  * @param vam vpp API test context
17193  * @return return code
17194  */
17195 static int
17196 api_one_pitr_set_locator_set (vat_main_t * vam)
17197 {
17198   u8 ls_name_set = 0;
17199   unformat_input_t *input = vam->input;
17200   vl_api_one_pitr_set_locator_set_t *mp;
17201   u8 is_add = 1;
17202   u8 *ls_name = 0;
17203   int ret;
17204
17205   /* Parse args required to build the message */
17206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17207     {
17208       if (unformat (input, "del"))
17209         is_add = 0;
17210       else if (unformat (input, "locator-set %s", &ls_name))
17211         ls_name_set = 1;
17212       else
17213         {
17214           errmsg ("parse error '%U'", format_unformat_error, input);
17215           return -99;
17216         }
17217     }
17218
17219   if (!ls_name_set)
17220     {
17221       errmsg ("locator-set name not set!");
17222       return -99;
17223     }
17224
17225   M (ONE_PITR_SET_LOCATOR_SET, mp);
17226
17227   mp->is_add = is_add;
17228   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17229   vec_free (ls_name);
17230
17231   /* send */
17232   S (mp);
17233
17234   /* wait for reply */
17235   W (ret);
17236   return ret;
17237 }
17238
17239 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17240
17241 static int
17242 api_one_nsh_set_locator_set (vat_main_t * vam)
17243 {
17244   u8 ls_name_set = 0;
17245   unformat_input_t *input = vam->input;
17246   vl_api_one_nsh_set_locator_set_t *mp;
17247   u8 is_add = 1;
17248   u8 *ls_name = 0;
17249   int ret;
17250
17251   /* Parse args required to build the message */
17252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17253     {
17254       if (unformat (input, "del"))
17255         is_add = 0;
17256       else if (unformat (input, "ls %s", &ls_name))
17257         ls_name_set = 1;
17258       else
17259         {
17260           errmsg ("parse error '%U'", format_unformat_error, input);
17261           return -99;
17262         }
17263     }
17264
17265   if (!ls_name_set && is_add)
17266     {
17267       errmsg ("locator-set name not set!");
17268       return -99;
17269     }
17270
17271   M (ONE_NSH_SET_LOCATOR_SET, mp);
17272
17273   mp->is_add = is_add;
17274   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17275   vec_free (ls_name);
17276
17277   /* send */
17278   S (mp);
17279
17280   /* wait for reply */
17281   W (ret);
17282   return ret;
17283 }
17284
17285 static int
17286 api_show_one_pitr (vat_main_t * vam)
17287 {
17288   vl_api_show_one_pitr_t *mp;
17289   int ret;
17290
17291   if (!vam->json_output)
17292     {
17293       print (vam->ofp, "%=20s", "lisp status:");
17294     }
17295
17296   M (SHOW_ONE_PITR, mp);
17297   /* send it... */
17298   S (mp);
17299
17300   /* Wait for a reply... */
17301   W (ret);
17302   return ret;
17303 }
17304
17305 #define api_show_lisp_pitr api_show_one_pitr
17306
17307 static int
17308 api_one_use_petr (vat_main_t * vam)
17309 {
17310   unformat_input_t *input = vam->input;
17311   vl_api_one_use_petr_t *mp;
17312   u8 is_add = 0;
17313   ip_address_t ip;
17314   int ret;
17315
17316   memset (&ip, 0, sizeof (ip));
17317
17318   /* Parse args required to build the message */
17319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17320     {
17321       if (unformat (input, "disable"))
17322         is_add = 0;
17323       else
17324         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17325         {
17326           is_add = 1;
17327           ip_addr_version (&ip) = IP4;
17328         }
17329       else
17330         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17331         {
17332           is_add = 1;
17333           ip_addr_version (&ip) = IP6;
17334         }
17335       else
17336         {
17337           errmsg ("parse error '%U'", format_unformat_error, input);
17338           return -99;
17339         }
17340     }
17341
17342   M (ONE_USE_PETR, mp);
17343
17344   mp->is_add = is_add;
17345   if (is_add)
17346     {
17347       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17348       if (mp->is_ip4)
17349         clib_memcpy (mp->address, &ip, 4);
17350       else
17351         clib_memcpy (mp->address, &ip, 16);
17352     }
17353
17354   /* send */
17355   S (mp);
17356
17357   /* wait for reply */
17358   W (ret);
17359   return ret;
17360 }
17361
17362 #define api_lisp_use_petr api_one_use_petr
17363
17364 static int
17365 api_show_one_nsh_mapping (vat_main_t * vam)
17366 {
17367   vl_api_show_one_use_petr_t *mp;
17368   int ret;
17369
17370   if (!vam->json_output)
17371     {
17372       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17373     }
17374
17375   M (SHOW_ONE_NSH_MAPPING, mp);
17376   /* send it... */
17377   S (mp);
17378
17379   /* Wait for a reply... */
17380   W (ret);
17381   return ret;
17382 }
17383
17384 static int
17385 api_show_one_use_petr (vat_main_t * vam)
17386 {
17387   vl_api_show_one_use_petr_t *mp;
17388   int ret;
17389
17390   if (!vam->json_output)
17391     {
17392       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17393     }
17394
17395   M (SHOW_ONE_USE_PETR, mp);
17396   /* send it... */
17397   S (mp);
17398
17399   /* Wait for a reply... */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 #define api_show_lisp_use_petr api_show_one_use_petr
17405
17406 /**
17407  * Add/delete mapping between vni and vrf
17408  */
17409 static int
17410 api_one_eid_table_add_del_map (vat_main_t * vam)
17411 {
17412   unformat_input_t *input = vam->input;
17413   vl_api_one_eid_table_add_del_map_t *mp;
17414   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17415   u32 vni, vrf, bd_index;
17416   int ret;
17417
17418   /* Parse args required to build the message */
17419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17420     {
17421       if (unformat (input, "del"))
17422         is_add = 0;
17423       else if (unformat (input, "vrf %d", &vrf))
17424         vrf_set = 1;
17425       else if (unformat (input, "bd_index %d", &bd_index))
17426         bd_index_set = 1;
17427       else if (unformat (input, "vni %d", &vni))
17428         vni_set = 1;
17429       else
17430         break;
17431     }
17432
17433   if (!vni_set || (!vrf_set && !bd_index_set))
17434     {
17435       errmsg ("missing arguments!");
17436       return -99;
17437     }
17438
17439   if (vrf_set && bd_index_set)
17440     {
17441       errmsg ("error: both vrf and bd entered!");
17442       return -99;
17443     }
17444
17445   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17446
17447   mp->is_add = is_add;
17448   mp->vni = htonl (vni);
17449   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17450   mp->is_l2 = bd_index_set;
17451
17452   /* send */
17453   S (mp);
17454
17455   /* wait for reply */
17456   W (ret);
17457   return ret;
17458 }
17459
17460 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17461
17462 uword
17463 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17464 {
17465   u32 *action = va_arg (*args, u32 *);
17466   u8 *s = 0;
17467
17468   if (unformat (input, "%s", &s))
17469     {
17470       if (!strcmp ((char *) s, "no-action"))
17471         action[0] = 0;
17472       else if (!strcmp ((char *) s, "natively-forward"))
17473         action[0] = 1;
17474       else if (!strcmp ((char *) s, "send-map-request"))
17475         action[0] = 2;
17476       else if (!strcmp ((char *) s, "drop"))
17477         action[0] = 3;
17478       else
17479         {
17480           clib_warning ("invalid action: '%s'", s);
17481           action[0] = 3;
17482         }
17483     }
17484   else
17485     return 0;
17486
17487   vec_free (s);
17488   return 1;
17489 }
17490
17491 /**
17492  * Add/del remote mapping to/from ONE control plane
17493  *
17494  * @param vam vpp API test context
17495  * @return return code
17496  */
17497 static int
17498 api_one_add_del_remote_mapping (vat_main_t * vam)
17499 {
17500   unformat_input_t *input = vam->input;
17501   vl_api_one_add_del_remote_mapping_t *mp;
17502   u32 vni = 0;
17503   lisp_eid_vat_t _eid, *eid = &_eid;
17504   lisp_eid_vat_t _seid, *seid = &_seid;
17505   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17506   u32 action = ~0, p, w, data_len;
17507   ip4_address_t rloc4;
17508   ip6_address_t rloc6;
17509   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17510   int ret;
17511
17512   memset (&rloc, 0, sizeof (rloc));
17513
17514   /* Parse args required to build the message */
17515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17516     {
17517       if (unformat (input, "del-all"))
17518         {
17519           del_all = 1;
17520         }
17521       else if (unformat (input, "del"))
17522         {
17523           is_add = 0;
17524         }
17525       else if (unformat (input, "add"))
17526         {
17527           is_add = 1;
17528         }
17529       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17530         {
17531           eid_set = 1;
17532         }
17533       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17534         {
17535           seid_set = 1;
17536         }
17537       else if (unformat (input, "vni %d", &vni))
17538         {
17539           ;
17540         }
17541       else if (unformat (input, "p %d w %d", &p, &w))
17542         {
17543           if (!curr_rloc)
17544             {
17545               errmsg ("No RLOC configured for setting priority/weight!");
17546               return -99;
17547             }
17548           curr_rloc->priority = p;
17549           curr_rloc->weight = w;
17550         }
17551       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17552         {
17553           rloc.is_ip4 = 1;
17554           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17555           vec_add1 (rlocs, rloc);
17556           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17557         }
17558       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17559         {
17560           rloc.is_ip4 = 0;
17561           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17562           vec_add1 (rlocs, rloc);
17563           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17564         }
17565       else if (unformat (input, "action %U",
17566                          unformat_negative_mapping_action, &action))
17567         {
17568           ;
17569         }
17570       else
17571         {
17572           clib_warning ("parse error '%U'", format_unformat_error, input);
17573           return -99;
17574         }
17575     }
17576
17577   if (0 == eid_set)
17578     {
17579       errmsg ("missing params!");
17580       return -99;
17581     }
17582
17583   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17584     {
17585       errmsg ("no action set for negative map-reply!");
17586       return -99;
17587     }
17588
17589   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17590
17591   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17592   mp->is_add = is_add;
17593   mp->vni = htonl (vni);
17594   mp->action = (u8) action;
17595   mp->is_src_dst = seid_set;
17596   mp->eid_len = eid->len;
17597   mp->seid_len = seid->len;
17598   mp->del_all = del_all;
17599   mp->eid_type = eid->type;
17600   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17601   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17602
17603   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17604   clib_memcpy (mp->rlocs, rlocs, data_len);
17605   vec_free (rlocs);
17606
17607   /* send it... */
17608   S (mp);
17609
17610   /* Wait for a reply... */
17611   W (ret);
17612   return ret;
17613 }
17614
17615 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17616
17617 /**
17618  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17619  * forwarding entries in data-plane accordingly.
17620  *
17621  * @param vam vpp API test context
17622  * @return return code
17623  */
17624 static int
17625 api_one_add_del_adjacency (vat_main_t * vam)
17626 {
17627   unformat_input_t *input = vam->input;
17628   vl_api_one_add_del_adjacency_t *mp;
17629   u32 vni = 0;
17630   ip4_address_t leid4, reid4;
17631   ip6_address_t leid6, reid6;
17632   u8 reid_mac[6] = { 0 };
17633   u8 leid_mac[6] = { 0 };
17634   u8 reid_type, leid_type;
17635   u32 leid_len = 0, reid_len = 0, len;
17636   u8 is_add = 1;
17637   int ret;
17638
17639   leid_type = reid_type = (u8) ~ 0;
17640
17641   /* Parse args required to build the message */
17642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17643     {
17644       if (unformat (input, "del"))
17645         {
17646           is_add = 0;
17647         }
17648       else if (unformat (input, "add"))
17649         {
17650           is_add = 1;
17651         }
17652       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17653                          &reid4, &len))
17654         {
17655           reid_type = 0;        /* ipv4 */
17656           reid_len = len;
17657         }
17658       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17659                          &reid6, &len))
17660         {
17661           reid_type = 1;        /* ipv6 */
17662           reid_len = len;
17663         }
17664       else if (unformat (input, "reid %U", unformat_ethernet_address,
17665                          reid_mac))
17666         {
17667           reid_type = 2;        /* mac */
17668         }
17669       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17670                          &leid4, &len))
17671         {
17672           leid_type = 0;        /* ipv4 */
17673           leid_len = len;
17674         }
17675       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17676                          &leid6, &len))
17677         {
17678           leid_type = 1;        /* ipv6 */
17679           leid_len = len;
17680         }
17681       else if (unformat (input, "leid %U", unformat_ethernet_address,
17682                          leid_mac))
17683         {
17684           leid_type = 2;        /* mac */
17685         }
17686       else if (unformat (input, "vni %d", &vni))
17687         {
17688           ;
17689         }
17690       else
17691         {
17692           errmsg ("parse error '%U'", format_unformat_error, input);
17693           return -99;
17694         }
17695     }
17696
17697   if ((u8) ~ 0 == reid_type)
17698     {
17699       errmsg ("missing params!");
17700       return -99;
17701     }
17702
17703   if (leid_type != reid_type)
17704     {
17705       errmsg ("remote and local EIDs are of different types!");
17706       return -99;
17707     }
17708
17709   M (ONE_ADD_DEL_ADJACENCY, mp);
17710   mp->is_add = is_add;
17711   mp->vni = htonl (vni);
17712   mp->leid_len = leid_len;
17713   mp->reid_len = reid_len;
17714   mp->eid_type = reid_type;
17715
17716   switch (mp->eid_type)
17717     {
17718     case 0:
17719       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17720       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17721       break;
17722     case 1:
17723       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17724       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17725       break;
17726     case 2:
17727       clib_memcpy (mp->leid, leid_mac, 6);
17728       clib_memcpy (mp->reid, reid_mac, 6);
17729       break;
17730     default:
17731       errmsg ("unknown EID type %d!", mp->eid_type);
17732       return 0;
17733     }
17734
17735   /* send it... */
17736   S (mp);
17737
17738   /* Wait for a reply... */
17739   W (ret);
17740   return ret;
17741 }
17742
17743 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17744
17745 uword
17746 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17747 {
17748   u32 *mode = va_arg (*args, u32 *);
17749
17750   if (unformat (input, "lisp"))
17751     *mode = 0;
17752   else if (unformat (input, "vxlan"))
17753     *mode = 1;
17754   else
17755     return 0;
17756
17757   return 1;
17758 }
17759
17760 static int
17761 api_gpe_get_encap_mode (vat_main_t * vam)
17762 {
17763   vl_api_gpe_get_encap_mode_t *mp;
17764   int ret;
17765
17766   /* Construct the API message */
17767   M (GPE_GET_ENCAP_MODE, mp);
17768
17769   /* send it... */
17770   S (mp);
17771
17772   /* Wait for a reply... */
17773   W (ret);
17774   return ret;
17775 }
17776
17777 static int
17778 api_gpe_set_encap_mode (vat_main_t * vam)
17779 {
17780   unformat_input_t *input = vam->input;
17781   vl_api_gpe_set_encap_mode_t *mp;
17782   int ret;
17783   u32 mode = 0;
17784
17785   /* Parse args required to build the message */
17786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17787     {
17788       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17789         ;
17790       else
17791         break;
17792     }
17793
17794   /* Construct the API message */
17795   M (GPE_SET_ENCAP_MODE, mp);
17796
17797   mp->mode = mode;
17798
17799   /* send it... */
17800   S (mp);
17801
17802   /* Wait for a reply... */
17803   W (ret);
17804   return ret;
17805 }
17806
17807 static int
17808 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17809 {
17810   unformat_input_t *input = vam->input;
17811   vl_api_gpe_add_del_iface_t *mp;
17812   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17813   u32 dp_table = 0, vni = 0;
17814   int ret;
17815
17816   /* Parse args required to build the message */
17817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (input, "up"))
17820         {
17821           action_set = 1;
17822           is_add = 1;
17823         }
17824       else if (unformat (input, "down"))
17825         {
17826           action_set = 1;
17827           is_add = 0;
17828         }
17829       else if (unformat (input, "table_id %d", &dp_table))
17830         {
17831           dp_table_set = 1;
17832         }
17833       else if (unformat (input, "bd_id %d", &dp_table))
17834         {
17835           dp_table_set = 1;
17836           is_l2 = 1;
17837         }
17838       else if (unformat (input, "vni %d", &vni))
17839         {
17840           vni_set = 1;
17841         }
17842       else
17843         break;
17844     }
17845
17846   if (action_set == 0)
17847     {
17848       errmsg ("Action not set");
17849       return -99;
17850     }
17851   if (dp_table_set == 0 || vni_set == 0)
17852     {
17853       errmsg ("vni and dp_table must be set");
17854       return -99;
17855     }
17856
17857   /* Construct the API message */
17858   M (GPE_ADD_DEL_IFACE, mp);
17859
17860   mp->is_add = is_add;
17861   mp->dp_table = clib_host_to_net_u32 (dp_table);
17862   mp->is_l2 = is_l2;
17863   mp->vni = clib_host_to_net_u32 (vni);
17864
17865   /* send it... */
17866   S (mp);
17867
17868   /* Wait for a reply... */
17869   W (ret);
17870   return ret;
17871 }
17872
17873 static int
17874 api_one_map_register_fallback_threshold (vat_main_t * vam)
17875 {
17876   unformat_input_t *input = vam->input;
17877   vl_api_one_map_register_fallback_threshold_t *mp;
17878   u32 value = 0;
17879   u8 is_set = 0;
17880   int ret;
17881
17882   /* Parse args required to build the message */
17883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17884     {
17885       if (unformat (input, "%u", &value))
17886         is_set = 1;
17887       else
17888         {
17889           clib_warning ("parse error '%U'", format_unformat_error, input);
17890           return -99;
17891         }
17892     }
17893
17894   if (!is_set)
17895     {
17896       errmsg ("fallback threshold value is missing!");
17897       return -99;
17898     }
17899
17900   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17901   mp->value = clib_host_to_net_u32 (value);
17902
17903   /* send it... */
17904   S (mp);
17905
17906   /* Wait for a reply... */
17907   W (ret);
17908   return ret;
17909 }
17910
17911 static int
17912 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17913 {
17914   vl_api_show_one_map_register_fallback_threshold_t *mp;
17915   int ret;
17916
17917   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17918
17919   /* send it... */
17920   S (mp);
17921
17922   /* Wait for a reply... */
17923   W (ret);
17924   return ret;
17925 }
17926
17927 uword
17928 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17929 {
17930   u32 *proto = va_arg (*args, u32 *);
17931
17932   if (unformat (input, "udp"))
17933     *proto = 1;
17934   else if (unformat (input, "api"))
17935     *proto = 2;
17936   else
17937     return 0;
17938
17939   return 1;
17940 }
17941
17942 static int
17943 api_one_set_transport_protocol (vat_main_t * vam)
17944 {
17945   unformat_input_t *input = vam->input;
17946   vl_api_one_set_transport_protocol_t *mp;
17947   u8 is_set = 0;
17948   u32 protocol = 0;
17949   int ret;
17950
17951   /* Parse args required to build the message */
17952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17953     {
17954       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17955         is_set = 1;
17956       else
17957         {
17958           clib_warning ("parse error '%U'", format_unformat_error, input);
17959           return -99;
17960         }
17961     }
17962
17963   if (!is_set)
17964     {
17965       errmsg ("Transport protocol missing!");
17966       return -99;
17967     }
17968
17969   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17970   mp->protocol = (u8) protocol;
17971
17972   /* send it... */
17973   S (mp);
17974
17975   /* Wait for a reply... */
17976   W (ret);
17977   return ret;
17978 }
17979
17980 static int
17981 api_one_get_transport_protocol (vat_main_t * vam)
17982 {
17983   vl_api_one_get_transport_protocol_t *mp;
17984   int ret;
17985
17986   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17987
17988   /* send it... */
17989   S (mp);
17990
17991   /* Wait for a reply... */
17992   W (ret);
17993   return ret;
17994 }
17995
17996 static int
17997 api_one_map_register_set_ttl (vat_main_t * vam)
17998 {
17999   unformat_input_t *input = vam->input;
18000   vl_api_one_map_register_set_ttl_t *mp;
18001   u32 ttl = 0;
18002   u8 is_set = 0;
18003   int ret;
18004
18005   /* Parse args required to build the message */
18006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18007     {
18008       if (unformat (input, "%u", &ttl))
18009         is_set = 1;
18010       else
18011         {
18012           clib_warning ("parse error '%U'", format_unformat_error, input);
18013           return -99;
18014         }
18015     }
18016
18017   if (!is_set)
18018     {
18019       errmsg ("TTL value missing!");
18020       return -99;
18021     }
18022
18023   M (ONE_MAP_REGISTER_SET_TTL, mp);
18024   mp->ttl = clib_host_to_net_u32 (ttl);
18025
18026   /* send it... */
18027   S (mp);
18028
18029   /* Wait for a reply... */
18030   W (ret);
18031   return ret;
18032 }
18033
18034 static int
18035 api_show_one_map_register_ttl (vat_main_t * vam)
18036 {
18037   vl_api_show_one_map_register_ttl_t *mp;
18038   int ret;
18039
18040   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18041
18042   /* send it... */
18043   S (mp);
18044
18045   /* Wait for a reply... */
18046   W (ret);
18047   return ret;
18048 }
18049
18050 /**
18051  * Add/del map request itr rlocs from ONE control plane and updates
18052  *
18053  * @param vam vpp API test context
18054  * @return return code
18055  */
18056 static int
18057 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18058 {
18059   unformat_input_t *input = vam->input;
18060   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18061   u8 *locator_set_name = 0;
18062   u8 locator_set_name_set = 0;
18063   u8 is_add = 1;
18064   int ret;
18065
18066   /* Parse args required to build the message */
18067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18068     {
18069       if (unformat (input, "del"))
18070         {
18071           is_add = 0;
18072         }
18073       else if (unformat (input, "%_%v%_", &locator_set_name))
18074         {
18075           locator_set_name_set = 1;
18076         }
18077       else
18078         {
18079           clib_warning ("parse error '%U'", format_unformat_error, input);
18080           return -99;
18081         }
18082     }
18083
18084   if (is_add && !locator_set_name_set)
18085     {
18086       errmsg ("itr-rloc is not set!");
18087       return -99;
18088     }
18089
18090   if (is_add && vec_len (locator_set_name) > 64)
18091     {
18092       errmsg ("itr-rloc locator-set name too long");
18093       vec_free (locator_set_name);
18094       return -99;
18095     }
18096
18097   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18098   mp->is_add = is_add;
18099   if (is_add)
18100     {
18101       clib_memcpy (mp->locator_set_name, locator_set_name,
18102                    vec_len (locator_set_name));
18103     }
18104   else
18105     {
18106       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18107     }
18108   vec_free (locator_set_name);
18109
18110   /* send it... */
18111   S (mp);
18112
18113   /* Wait for a reply... */
18114   W (ret);
18115   return ret;
18116 }
18117
18118 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18119
18120 static int
18121 api_one_locator_dump (vat_main_t * vam)
18122 {
18123   unformat_input_t *input = vam->input;
18124   vl_api_one_locator_dump_t *mp;
18125   vl_api_control_ping_t *mp_ping;
18126   u8 is_index_set = 0, is_name_set = 0;
18127   u8 *ls_name = 0;
18128   u32 ls_index = ~0;
18129   int ret;
18130
18131   /* Parse args required to build the message */
18132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18133     {
18134       if (unformat (input, "ls_name %_%v%_", &ls_name))
18135         {
18136           is_name_set = 1;
18137         }
18138       else if (unformat (input, "ls_index %d", &ls_index))
18139         {
18140           is_index_set = 1;
18141         }
18142       else
18143         {
18144           errmsg ("parse error '%U'", format_unformat_error, input);
18145           return -99;
18146         }
18147     }
18148
18149   if (!is_index_set && !is_name_set)
18150     {
18151       errmsg ("error: expected one of index or name!");
18152       return -99;
18153     }
18154
18155   if (is_index_set && is_name_set)
18156     {
18157       errmsg ("error: only one param expected!");
18158       return -99;
18159     }
18160
18161   if (vec_len (ls_name) > 62)
18162     {
18163       errmsg ("error: locator set name too long!");
18164       return -99;
18165     }
18166
18167   if (!vam->json_output)
18168     {
18169       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18170     }
18171
18172   M (ONE_LOCATOR_DUMP, mp);
18173   mp->is_index_set = is_index_set;
18174
18175   if (is_index_set)
18176     mp->ls_index = clib_host_to_net_u32 (ls_index);
18177   else
18178     {
18179       vec_add1 (ls_name, 0);
18180       strncpy ((char *) mp->ls_name, (char *) ls_name,
18181                sizeof (mp->ls_name) - 1);
18182     }
18183
18184   /* send it... */
18185   S (mp);
18186
18187   /* Use a control ping for synchronization */
18188   MPING (CONTROL_PING, mp_ping);
18189   S (mp_ping);
18190
18191   /* Wait for a reply... */
18192   W (ret);
18193   return ret;
18194 }
18195
18196 #define api_lisp_locator_dump api_one_locator_dump
18197
18198 static int
18199 api_one_locator_set_dump (vat_main_t * vam)
18200 {
18201   vl_api_one_locator_set_dump_t *mp;
18202   vl_api_control_ping_t *mp_ping;
18203   unformat_input_t *input = vam->input;
18204   u8 filter = 0;
18205   int ret;
18206
18207   /* Parse args required to build the message */
18208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18209     {
18210       if (unformat (input, "local"))
18211         {
18212           filter = 1;
18213         }
18214       else if (unformat (input, "remote"))
18215         {
18216           filter = 2;
18217         }
18218       else
18219         {
18220           errmsg ("parse error '%U'", format_unformat_error, input);
18221           return -99;
18222         }
18223     }
18224
18225   if (!vam->json_output)
18226     {
18227       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18228     }
18229
18230   M (ONE_LOCATOR_SET_DUMP, mp);
18231
18232   mp->filter = filter;
18233
18234   /* send it... */
18235   S (mp);
18236
18237   /* Use a control ping for synchronization */
18238   MPING (CONTROL_PING, mp_ping);
18239   S (mp_ping);
18240
18241   /* Wait for a reply... */
18242   W (ret);
18243   return ret;
18244 }
18245
18246 #define api_lisp_locator_set_dump api_one_locator_set_dump
18247
18248 static int
18249 api_one_eid_table_map_dump (vat_main_t * vam)
18250 {
18251   u8 is_l2 = 0;
18252   u8 mode_set = 0;
18253   unformat_input_t *input = vam->input;
18254   vl_api_one_eid_table_map_dump_t *mp;
18255   vl_api_control_ping_t *mp_ping;
18256   int ret;
18257
18258   /* Parse args required to build the message */
18259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18260     {
18261       if (unformat (input, "l2"))
18262         {
18263           is_l2 = 1;
18264           mode_set = 1;
18265         }
18266       else if (unformat (input, "l3"))
18267         {
18268           is_l2 = 0;
18269           mode_set = 1;
18270         }
18271       else
18272         {
18273           errmsg ("parse error '%U'", format_unformat_error, input);
18274           return -99;
18275         }
18276     }
18277
18278   if (!mode_set)
18279     {
18280       errmsg ("expected one of 'l2' or 'l3' parameter!");
18281       return -99;
18282     }
18283
18284   if (!vam->json_output)
18285     {
18286       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18287     }
18288
18289   M (ONE_EID_TABLE_MAP_DUMP, mp);
18290   mp->is_l2 = is_l2;
18291
18292   /* send it... */
18293   S (mp);
18294
18295   /* Use a control ping for synchronization */
18296   MPING (CONTROL_PING, mp_ping);
18297   S (mp_ping);
18298
18299   /* Wait for a reply... */
18300   W (ret);
18301   return ret;
18302 }
18303
18304 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18305
18306 static int
18307 api_one_eid_table_vni_dump (vat_main_t * vam)
18308 {
18309   vl_api_one_eid_table_vni_dump_t *mp;
18310   vl_api_control_ping_t *mp_ping;
18311   int ret;
18312
18313   if (!vam->json_output)
18314     {
18315       print (vam->ofp, "VNI");
18316     }
18317
18318   M (ONE_EID_TABLE_VNI_DUMP, mp);
18319
18320   /* send it... */
18321   S (mp);
18322
18323   /* Use a control ping for synchronization */
18324   MPING (CONTROL_PING, mp_ping);
18325   S (mp_ping);
18326
18327   /* Wait for a reply... */
18328   W (ret);
18329   return ret;
18330 }
18331
18332 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18333
18334 static int
18335 api_one_eid_table_dump (vat_main_t * vam)
18336 {
18337   unformat_input_t *i = vam->input;
18338   vl_api_one_eid_table_dump_t *mp;
18339   vl_api_control_ping_t *mp_ping;
18340   struct in_addr ip4;
18341   struct in6_addr ip6;
18342   u8 mac[6];
18343   u8 eid_type = ~0, eid_set = 0;
18344   u32 prefix_length = ~0, t, vni = 0;
18345   u8 filter = 0;
18346   int ret;
18347   lisp_nsh_api_t nsh;
18348
18349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18350     {
18351       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18352         {
18353           eid_set = 1;
18354           eid_type = 0;
18355           prefix_length = t;
18356         }
18357       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18358         {
18359           eid_set = 1;
18360           eid_type = 1;
18361           prefix_length = t;
18362         }
18363       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18364         {
18365           eid_set = 1;
18366           eid_type = 2;
18367         }
18368       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18369         {
18370           eid_set = 1;
18371           eid_type = 3;
18372         }
18373       else if (unformat (i, "vni %d", &t))
18374         {
18375           vni = t;
18376         }
18377       else if (unformat (i, "local"))
18378         {
18379           filter = 1;
18380         }
18381       else if (unformat (i, "remote"))
18382         {
18383           filter = 2;
18384         }
18385       else
18386         {
18387           errmsg ("parse error '%U'", format_unformat_error, i);
18388           return -99;
18389         }
18390     }
18391
18392   if (!vam->json_output)
18393     {
18394       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18395              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18396     }
18397
18398   M (ONE_EID_TABLE_DUMP, mp);
18399
18400   mp->filter = filter;
18401   if (eid_set)
18402     {
18403       mp->eid_set = 1;
18404       mp->vni = htonl (vni);
18405       mp->eid_type = eid_type;
18406       switch (eid_type)
18407         {
18408         case 0:
18409           mp->prefix_length = prefix_length;
18410           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18411           break;
18412         case 1:
18413           mp->prefix_length = prefix_length;
18414           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18415           break;
18416         case 2:
18417           clib_memcpy (mp->eid, mac, sizeof (mac));
18418           break;
18419         case 3:
18420           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18421           break;
18422         default:
18423           errmsg ("unknown EID type %d!", eid_type);
18424           return -99;
18425         }
18426     }
18427
18428   /* send it... */
18429   S (mp);
18430
18431   /* Use a control ping for synchronization */
18432   MPING (CONTROL_PING, mp_ping);
18433   S (mp_ping);
18434
18435   /* Wait for a reply... */
18436   W (ret);
18437   return ret;
18438 }
18439
18440 #define api_lisp_eid_table_dump api_one_eid_table_dump
18441
18442 static int
18443 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18444 {
18445   unformat_input_t *i = vam->input;
18446   vl_api_gpe_fwd_entries_get_t *mp;
18447   u8 vni_set = 0;
18448   u32 vni = ~0;
18449   int ret;
18450
18451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18452     {
18453       if (unformat (i, "vni %d", &vni))
18454         {
18455           vni_set = 1;
18456         }
18457       else
18458         {
18459           errmsg ("parse error '%U'", format_unformat_error, i);
18460           return -99;
18461         }
18462     }
18463
18464   if (!vni_set)
18465     {
18466       errmsg ("vni not set!");
18467       return -99;
18468     }
18469
18470   if (!vam->json_output)
18471     {
18472       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18473              "leid", "reid");
18474     }
18475
18476   M (GPE_FWD_ENTRIES_GET, mp);
18477   mp->vni = clib_host_to_net_u32 (vni);
18478
18479   /* send it... */
18480   S (mp);
18481
18482   /* Wait for a reply... */
18483   W (ret);
18484   return ret;
18485 }
18486
18487 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18488 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18489 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18490 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18491 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18492 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18493 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18494 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18495
18496 static int
18497 api_one_adjacencies_get (vat_main_t * vam)
18498 {
18499   unformat_input_t *i = vam->input;
18500   vl_api_one_adjacencies_get_t *mp;
18501   u8 vni_set = 0;
18502   u32 vni = ~0;
18503   int ret;
18504
18505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18506     {
18507       if (unformat (i, "vni %d", &vni))
18508         {
18509           vni_set = 1;
18510         }
18511       else
18512         {
18513           errmsg ("parse error '%U'", format_unformat_error, i);
18514           return -99;
18515         }
18516     }
18517
18518   if (!vni_set)
18519     {
18520       errmsg ("vni not set!");
18521       return -99;
18522     }
18523
18524   if (!vam->json_output)
18525     {
18526       print (vam->ofp, "%s %40s", "leid", "reid");
18527     }
18528
18529   M (ONE_ADJACENCIES_GET, mp);
18530   mp->vni = clib_host_to_net_u32 (vni);
18531
18532   /* send it... */
18533   S (mp);
18534
18535   /* Wait for a reply... */
18536   W (ret);
18537   return ret;
18538 }
18539
18540 #define api_lisp_adjacencies_get api_one_adjacencies_get
18541
18542 static int
18543 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18544 {
18545   unformat_input_t *i = vam->input;
18546   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18547   int ret;
18548   u8 ip_family_set = 0, is_ip4 = 1;
18549
18550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18551     {
18552       if (unformat (i, "ip4"))
18553         {
18554           ip_family_set = 1;
18555           is_ip4 = 1;
18556         }
18557       else if (unformat (i, "ip6"))
18558         {
18559           ip_family_set = 1;
18560           is_ip4 = 0;
18561         }
18562       else
18563         {
18564           errmsg ("parse error '%U'", format_unformat_error, i);
18565           return -99;
18566         }
18567     }
18568
18569   if (!ip_family_set)
18570     {
18571       errmsg ("ip family not set!");
18572       return -99;
18573     }
18574
18575   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18576   mp->is_ip4 = is_ip4;
18577
18578   /* send it... */
18579   S (mp);
18580
18581   /* Wait for a reply... */
18582   W (ret);
18583   return ret;
18584 }
18585
18586 static int
18587 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18588 {
18589   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18590   int ret;
18591
18592   if (!vam->json_output)
18593     {
18594       print (vam->ofp, "VNIs");
18595     }
18596
18597   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18598
18599   /* send it... */
18600   S (mp);
18601
18602   /* Wait for a reply... */
18603   W (ret);
18604   return ret;
18605 }
18606
18607 static int
18608 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18609 {
18610   unformat_input_t *i = vam->input;
18611   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18612   int ret = 0;
18613   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18614   struct in_addr ip4;
18615   struct in6_addr ip6;
18616   u32 table_id = 0, nh_sw_if_index = ~0;
18617
18618   memset (&ip4, 0, sizeof (ip4));
18619   memset (&ip6, 0, sizeof (ip6));
18620
18621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18622     {
18623       if (unformat (i, "del"))
18624         is_add = 0;
18625       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18626                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18627         {
18628           ip_set = 1;
18629           is_ip4 = 1;
18630         }
18631       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18632                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18633         {
18634           ip_set = 1;
18635           is_ip4 = 0;
18636         }
18637       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18638         {
18639           ip_set = 1;
18640           is_ip4 = 1;
18641           nh_sw_if_index = ~0;
18642         }
18643       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18644         {
18645           ip_set = 1;
18646           is_ip4 = 0;
18647           nh_sw_if_index = ~0;
18648         }
18649       else if (unformat (i, "table %d", &table_id))
18650         ;
18651       else
18652         {
18653           errmsg ("parse error '%U'", format_unformat_error, i);
18654           return -99;
18655         }
18656     }
18657
18658   if (!ip_set)
18659     {
18660       errmsg ("nh addr not set!");
18661       return -99;
18662     }
18663
18664   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18665   mp->is_add = is_add;
18666   mp->table_id = clib_host_to_net_u32 (table_id);
18667   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18668   mp->is_ip4 = is_ip4;
18669   if (is_ip4)
18670     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18671   else
18672     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18673
18674   /* send it... */
18675   S (mp);
18676
18677   /* Wait for a reply... */
18678   W (ret);
18679   return ret;
18680 }
18681
18682 static int
18683 api_one_map_server_dump (vat_main_t * vam)
18684 {
18685   vl_api_one_map_server_dump_t *mp;
18686   vl_api_control_ping_t *mp_ping;
18687   int ret;
18688
18689   if (!vam->json_output)
18690     {
18691       print (vam->ofp, "%=20s", "Map server");
18692     }
18693
18694   M (ONE_MAP_SERVER_DUMP, mp);
18695   /* send it... */
18696   S (mp);
18697
18698   /* Use a control ping for synchronization */
18699   MPING (CONTROL_PING, mp_ping);
18700   S (mp_ping);
18701
18702   /* Wait for a reply... */
18703   W (ret);
18704   return ret;
18705 }
18706
18707 #define api_lisp_map_server_dump api_one_map_server_dump
18708
18709 static int
18710 api_one_map_resolver_dump (vat_main_t * vam)
18711 {
18712   vl_api_one_map_resolver_dump_t *mp;
18713   vl_api_control_ping_t *mp_ping;
18714   int ret;
18715
18716   if (!vam->json_output)
18717     {
18718       print (vam->ofp, "%=20s", "Map resolver");
18719     }
18720
18721   M (ONE_MAP_RESOLVER_DUMP, mp);
18722   /* send it... */
18723   S (mp);
18724
18725   /* Use a control ping for synchronization */
18726   MPING (CONTROL_PING, mp_ping);
18727   S (mp_ping);
18728
18729   /* Wait for a reply... */
18730   W (ret);
18731   return ret;
18732 }
18733
18734 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18735
18736 static int
18737 api_one_stats_flush (vat_main_t * vam)
18738 {
18739   vl_api_one_stats_flush_t *mp;
18740   int ret = 0;
18741
18742   M (ONE_STATS_FLUSH, mp);
18743   S (mp);
18744   W (ret);
18745   return ret;
18746 }
18747
18748 static int
18749 api_one_stats_dump (vat_main_t * vam)
18750 {
18751   vl_api_one_stats_dump_t *mp;
18752   vl_api_control_ping_t *mp_ping;
18753   int ret;
18754
18755   M (ONE_STATS_DUMP, mp);
18756   /* send it... */
18757   S (mp);
18758
18759   /* Use a control ping for synchronization */
18760   MPING (CONTROL_PING, mp_ping);
18761   S (mp_ping);
18762
18763   /* Wait for a reply... */
18764   W (ret);
18765   return ret;
18766 }
18767
18768 static int
18769 api_show_one_status (vat_main_t * vam)
18770 {
18771   vl_api_show_one_status_t *mp;
18772   int ret;
18773
18774   if (!vam->json_output)
18775     {
18776       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18777     }
18778
18779   M (SHOW_ONE_STATUS, mp);
18780   /* send it... */
18781   S (mp);
18782   /* Wait for a reply... */
18783   W (ret);
18784   return ret;
18785 }
18786
18787 #define api_show_lisp_status api_show_one_status
18788
18789 static int
18790 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18791 {
18792   vl_api_gpe_fwd_entry_path_dump_t *mp;
18793   vl_api_control_ping_t *mp_ping;
18794   unformat_input_t *i = vam->input;
18795   u32 fwd_entry_index = ~0;
18796   int ret;
18797
18798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18799     {
18800       if (unformat (i, "index %d", &fwd_entry_index))
18801         ;
18802       else
18803         break;
18804     }
18805
18806   if (~0 == fwd_entry_index)
18807     {
18808       errmsg ("no index specified!");
18809       return -99;
18810     }
18811
18812   if (!vam->json_output)
18813     {
18814       print (vam->ofp, "first line");
18815     }
18816
18817   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18818
18819   /* send it... */
18820   S (mp);
18821   /* Use a control ping for synchronization */
18822   MPING (CONTROL_PING, mp_ping);
18823   S (mp_ping);
18824
18825   /* Wait for a reply... */
18826   W (ret);
18827   return ret;
18828 }
18829
18830 static int
18831 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18832 {
18833   vl_api_one_get_map_request_itr_rlocs_t *mp;
18834   int ret;
18835
18836   if (!vam->json_output)
18837     {
18838       print (vam->ofp, "%=20s", "itr-rlocs:");
18839     }
18840
18841   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18842   /* send it... */
18843   S (mp);
18844   /* Wait for a reply... */
18845   W (ret);
18846   return ret;
18847 }
18848
18849 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18850
18851 static int
18852 api_af_packet_create (vat_main_t * vam)
18853 {
18854   unformat_input_t *i = vam->input;
18855   vl_api_af_packet_create_t *mp;
18856   u8 *host_if_name = 0;
18857   u8 hw_addr[6];
18858   u8 random_hw_addr = 1;
18859   int ret;
18860
18861   memset (hw_addr, 0, sizeof (hw_addr));
18862
18863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18864     {
18865       if (unformat (i, "name %s", &host_if_name))
18866         vec_add1 (host_if_name, 0);
18867       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18868         random_hw_addr = 0;
18869       else
18870         break;
18871     }
18872
18873   if (!vec_len (host_if_name))
18874     {
18875       errmsg ("host-interface name must be specified");
18876       return -99;
18877     }
18878
18879   if (vec_len (host_if_name) > 64)
18880     {
18881       errmsg ("host-interface name too long");
18882       return -99;
18883     }
18884
18885   M (AF_PACKET_CREATE, mp);
18886
18887   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18888   clib_memcpy (mp->hw_addr, hw_addr, 6);
18889   mp->use_random_hw_addr = random_hw_addr;
18890   vec_free (host_if_name);
18891
18892   S (mp);
18893
18894   /* *INDENT-OFF* */
18895   W2 (ret,
18896       ({
18897         if (ret == 0)
18898           fprintf (vam->ofp ? vam->ofp : stderr,
18899                    " new sw_if_index = %d\n", vam->sw_if_index);
18900       }));
18901   /* *INDENT-ON* */
18902   return ret;
18903 }
18904
18905 static int
18906 api_af_packet_delete (vat_main_t * vam)
18907 {
18908   unformat_input_t *i = vam->input;
18909   vl_api_af_packet_delete_t *mp;
18910   u8 *host_if_name = 0;
18911   int ret;
18912
18913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18914     {
18915       if (unformat (i, "name %s", &host_if_name))
18916         vec_add1 (host_if_name, 0);
18917       else
18918         break;
18919     }
18920
18921   if (!vec_len (host_if_name))
18922     {
18923       errmsg ("host-interface name must be specified");
18924       return -99;
18925     }
18926
18927   if (vec_len (host_if_name) > 64)
18928     {
18929       errmsg ("host-interface name too long");
18930       return -99;
18931     }
18932
18933   M (AF_PACKET_DELETE, mp);
18934
18935   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18936   vec_free (host_if_name);
18937
18938   S (mp);
18939   W (ret);
18940   return ret;
18941 }
18942
18943 static int
18944 api_policer_add_del (vat_main_t * vam)
18945 {
18946   unformat_input_t *i = vam->input;
18947   vl_api_policer_add_del_t *mp;
18948   u8 is_add = 1;
18949   u8 *name = 0;
18950   u32 cir = 0;
18951   u32 eir = 0;
18952   u64 cb = 0;
18953   u64 eb = 0;
18954   u8 rate_type = 0;
18955   u8 round_type = 0;
18956   u8 type = 0;
18957   u8 color_aware = 0;
18958   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18959   int ret;
18960
18961   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18962   conform_action.dscp = 0;
18963   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18964   exceed_action.dscp = 0;
18965   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18966   violate_action.dscp = 0;
18967
18968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18969     {
18970       if (unformat (i, "del"))
18971         is_add = 0;
18972       else if (unformat (i, "name %s", &name))
18973         vec_add1 (name, 0);
18974       else if (unformat (i, "cir %u", &cir))
18975         ;
18976       else if (unformat (i, "eir %u", &eir))
18977         ;
18978       else if (unformat (i, "cb %u", &cb))
18979         ;
18980       else if (unformat (i, "eb %u", &eb))
18981         ;
18982       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18983                          &rate_type))
18984         ;
18985       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18986                          &round_type))
18987         ;
18988       else if (unformat (i, "type %U", unformat_policer_type, &type))
18989         ;
18990       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18991                          &conform_action))
18992         ;
18993       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18994                          &exceed_action))
18995         ;
18996       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18997                          &violate_action))
18998         ;
18999       else if (unformat (i, "color-aware"))
19000         color_aware = 1;
19001       else
19002         break;
19003     }
19004
19005   if (!vec_len (name))
19006     {
19007       errmsg ("policer name must be specified");
19008       return -99;
19009     }
19010
19011   if (vec_len (name) > 64)
19012     {
19013       errmsg ("policer name too long");
19014       return -99;
19015     }
19016
19017   M (POLICER_ADD_DEL, mp);
19018
19019   clib_memcpy (mp->name, name, vec_len (name));
19020   vec_free (name);
19021   mp->is_add = is_add;
19022   mp->cir = ntohl (cir);
19023   mp->eir = ntohl (eir);
19024   mp->cb = clib_net_to_host_u64 (cb);
19025   mp->eb = clib_net_to_host_u64 (eb);
19026   mp->rate_type = rate_type;
19027   mp->round_type = round_type;
19028   mp->type = type;
19029   mp->conform_action_type = conform_action.action_type;
19030   mp->conform_dscp = conform_action.dscp;
19031   mp->exceed_action_type = exceed_action.action_type;
19032   mp->exceed_dscp = exceed_action.dscp;
19033   mp->violate_action_type = violate_action.action_type;
19034   mp->violate_dscp = violate_action.dscp;
19035   mp->color_aware = color_aware;
19036
19037   S (mp);
19038   W (ret);
19039   return ret;
19040 }
19041
19042 static int
19043 api_policer_dump (vat_main_t * vam)
19044 {
19045   unformat_input_t *i = vam->input;
19046   vl_api_policer_dump_t *mp;
19047   vl_api_control_ping_t *mp_ping;
19048   u8 *match_name = 0;
19049   u8 match_name_valid = 0;
19050   int ret;
19051
19052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19053     {
19054       if (unformat (i, "name %s", &match_name))
19055         {
19056           vec_add1 (match_name, 0);
19057           match_name_valid = 1;
19058         }
19059       else
19060         break;
19061     }
19062
19063   M (POLICER_DUMP, mp);
19064   mp->match_name_valid = match_name_valid;
19065   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19066   vec_free (match_name);
19067   /* send it... */
19068   S (mp);
19069
19070   /* Use a control ping for synchronization */
19071   MPING (CONTROL_PING, mp_ping);
19072   S (mp_ping);
19073
19074   /* Wait for a reply... */
19075   W (ret);
19076   return ret;
19077 }
19078
19079 static int
19080 api_policer_classify_set_interface (vat_main_t * vam)
19081 {
19082   unformat_input_t *i = vam->input;
19083   vl_api_policer_classify_set_interface_t *mp;
19084   u32 sw_if_index;
19085   int sw_if_index_set;
19086   u32 ip4_table_index = ~0;
19087   u32 ip6_table_index = ~0;
19088   u32 l2_table_index = ~0;
19089   u8 is_add = 1;
19090   int ret;
19091
19092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19093     {
19094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19095         sw_if_index_set = 1;
19096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19097         sw_if_index_set = 1;
19098       else if (unformat (i, "del"))
19099         is_add = 0;
19100       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19101         ;
19102       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19103         ;
19104       else if (unformat (i, "l2-table %d", &l2_table_index))
19105         ;
19106       else
19107         {
19108           clib_warning ("parse error '%U'", format_unformat_error, i);
19109           return -99;
19110         }
19111     }
19112
19113   if (sw_if_index_set == 0)
19114     {
19115       errmsg ("missing interface name or sw_if_index");
19116       return -99;
19117     }
19118
19119   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19120
19121   mp->sw_if_index = ntohl (sw_if_index);
19122   mp->ip4_table_index = ntohl (ip4_table_index);
19123   mp->ip6_table_index = ntohl (ip6_table_index);
19124   mp->l2_table_index = ntohl (l2_table_index);
19125   mp->is_add = is_add;
19126
19127   S (mp);
19128   W (ret);
19129   return ret;
19130 }
19131
19132 static int
19133 api_policer_classify_dump (vat_main_t * vam)
19134 {
19135   unformat_input_t *i = vam->input;
19136   vl_api_policer_classify_dump_t *mp;
19137   vl_api_control_ping_t *mp_ping;
19138   u8 type = POLICER_CLASSIFY_N_TABLES;
19139   int ret;
19140
19141   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19142     ;
19143   else
19144     {
19145       errmsg ("classify table type must be specified");
19146       return -99;
19147     }
19148
19149   if (!vam->json_output)
19150     {
19151       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19152     }
19153
19154   M (POLICER_CLASSIFY_DUMP, mp);
19155   mp->type = type;
19156   /* send it... */
19157   S (mp);
19158
19159   /* Use a control ping for synchronization */
19160   MPING (CONTROL_PING, mp_ping);
19161   S (mp_ping);
19162
19163   /* Wait for a reply... */
19164   W (ret);
19165   return ret;
19166 }
19167
19168 static int
19169 api_netmap_create (vat_main_t * vam)
19170 {
19171   unformat_input_t *i = vam->input;
19172   vl_api_netmap_create_t *mp;
19173   u8 *if_name = 0;
19174   u8 hw_addr[6];
19175   u8 random_hw_addr = 1;
19176   u8 is_pipe = 0;
19177   u8 is_master = 0;
19178   int ret;
19179
19180   memset (hw_addr, 0, sizeof (hw_addr));
19181
19182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19183     {
19184       if (unformat (i, "name %s", &if_name))
19185         vec_add1 (if_name, 0);
19186       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19187         random_hw_addr = 0;
19188       else if (unformat (i, "pipe"))
19189         is_pipe = 1;
19190       else if (unformat (i, "master"))
19191         is_master = 1;
19192       else if (unformat (i, "slave"))
19193         is_master = 0;
19194       else
19195         break;
19196     }
19197
19198   if (!vec_len (if_name))
19199     {
19200       errmsg ("interface name must be specified");
19201       return -99;
19202     }
19203
19204   if (vec_len (if_name) > 64)
19205     {
19206       errmsg ("interface name too long");
19207       return -99;
19208     }
19209
19210   M (NETMAP_CREATE, mp);
19211
19212   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19213   clib_memcpy (mp->hw_addr, hw_addr, 6);
19214   mp->use_random_hw_addr = random_hw_addr;
19215   mp->is_pipe = is_pipe;
19216   mp->is_master = is_master;
19217   vec_free (if_name);
19218
19219   S (mp);
19220   W (ret);
19221   return ret;
19222 }
19223
19224 static int
19225 api_netmap_delete (vat_main_t * vam)
19226 {
19227   unformat_input_t *i = vam->input;
19228   vl_api_netmap_delete_t *mp;
19229   u8 *if_name = 0;
19230   int ret;
19231
19232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19233     {
19234       if (unformat (i, "name %s", &if_name))
19235         vec_add1 (if_name, 0);
19236       else
19237         break;
19238     }
19239
19240   if (!vec_len (if_name))
19241     {
19242       errmsg ("interface name must be specified");
19243       return -99;
19244     }
19245
19246   if (vec_len (if_name) > 64)
19247     {
19248       errmsg ("interface name too long");
19249       return -99;
19250     }
19251
19252   M (NETMAP_DELETE, mp);
19253
19254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19255   vec_free (if_name);
19256
19257   S (mp);
19258   W (ret);
19259   return ret;
19260 }
19261
19262 static void
19263 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19264 {
19265   if (fp->afi == IP46_TYPE_IP6)
19266     print (vam->ofp,
19267            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19268            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19269            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19270            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19271            format_ip6_address, fp->next_hop);
19272   else if (fp->afi == IP46_TYPE_IP4)
19273     print (vam->ofp,
19274            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19275            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19276            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19277            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19278            format_ip4_address, fp->next_hop);
19279 }
19280
19281 static void
19282 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19283                                  vl_api_fib_path2_t * fp)
19284 {
19285   struct in_addr ip4;
19286   struct in6_addr ip6;
19287
19288   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19289   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19290   vat_json_object_add_uint (node, "is_local", fp->is_local);
19291   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19292   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19293   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19294   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19295   if (fp->afi == IP46_TYPE_IP4)
19296     {
19297       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19298       vat_json_object_add_ip4 (node, "next_hop", ip4);
19299     }
19300   else if (fp->afi == IP46_TYPE_IP6)
19301     {
19302       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19303       vat_json_object_add_ip6 (node, "next_hop", ip6);
19304     }
19305 }
19306
19307 static void
19308 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19309 {
19310   vat_main_t *vam = &vat_main;
19311   int count = ntohl (mp->mt_count);
19312   vl_api_fib_path2_t *fp;
19313   i32 i;
19314
19315   print (vam->ofp, "[%d]: sw_if_index %d via:",
19316          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19317   fp = mp->mt_paths;
19318   for (i = 0; i < count; i++)
19319     {
19320       vl_api_mpls_fib_path_print (vam, fp);
19321       fp++;
19322     }
19323
19324   print (vam->ofp, "");
19325 }
19326
19327 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19328 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19329
19330 static void
19331 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19332 {
19333   vat_main_t *vam = &vat_main;
19334   vat_json_node_t *node = NULL;
19335   int count = ntohl (mp->mt_count);
19336   vl_api_fib_path2_t *fp;
19337   i32 i;
19338
19339   if (VAT_JSON_ARRAY != vam->json_tree.type)
19340     {
19341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19342       vat_json_init_array (&vam->json_tree);
19343     }
19344   node = vat_json_array_add (&vam->json_tree);
19345
19346   vat_json_init_object (node);
19347   vat_json_object_add_uint (node, "tunnel_index",
19348                             ntohl (mp->mt_tunnel_index));
19349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19350
19351   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19352
19353   fp = mp->mt_paths;
19354   for (i = 0; i < count; i++)
19355     {
19356       vl_api_mpls_fib_path_json_print (node, fp);
19357       fp++;
19358     }
19359 }
19360
19361 static int
19362 api_mpls_tunnel_dump (vat_main_t * vam)
19363 {
19364   vl_api_mpls_tunnel_dump_t *mp;
19365   vl_api_control_ping_t *mp_ping;
19366   i32 index = -1;
19367   int ret;
19368
19369   /* Parse args required to build the message */
19370   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19371     {
19372       if (!unformat (vam->input, "tunnel_index %d", &index))
19373         {
19374           index = -1;
19375           break;
19376         }
19377     }
19378
19379   print (vam->ofp, "  tunnel_index %d", index);
19380
19381   M (MPLS_TUNNEL_DUMP, mp);
19382   mp->tunnel_index = htonl (index);
19383   S (mp);
19384
19385   /* Use a control ping for synchronization */
19386   MPING (CONTROL_PING, mp_ping);
19387   S (mp_ping);
19388
19389   W (ret);
19390   return ret;
19391 }
19392
19393 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19394 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19395
19396
19397 static void
19398 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19399 {
19400   vat_main_t *vam = &vat_main;
19401   int count = ntohl (mp->count);
19402   vl_api_fib_path2_t *fp;
19403   int i;
19404
19405   print (vam->ofp,
19406          "table-id %d, label %u, ess_bit %u",
19407          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19408   fp = mp->path;
19409   for (i = 0; i < count; i++)
19410     {
19411       vl_api_mpls_fib_path_print (vam, fp);
19412       fp++;
19413     }
19414 }
19415
19416 static void vl_api_mpls_fib_details_t_handler_json
19417   (vl_api_mpls_fib_details_t * mp)
19418 {
19419   vat_main_t *vam = &vat_main;
19420   int count = ntohl (mp->count);
19421   vat_json_node_t *node = NULL;
19422   vl_api_fib_path2_t *fp;
19423   int i;
19424
19425   if (VAT_JSON_ARRAY != vam->json_tree.type)
19426     {
19427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19428       vat_json_init_array (&vam->json_tree);
19429     }
19430   node = vat_json_array_add (&vam->json_tree);
19431
19432   vat_json_init_object (node);
19433   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19434   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19435   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19436   vat_json_object_add_uint (node, "path_count", count);
19437   fp = mp->path;
19438   for (i = 0; i < count; i++)
19439     {
19440       vl_api_mpls_fib_path_json_print (node, fp);
19441       fp++;
19442     }
19443 }
19444
19445 static int
19446 api_mpls_fib_dump (vat_main_t * vam)
19447 {
19448   vl_api_mpls_fib_dump_t *mp;
19449   vl_api_control_ping_t *mp_ping;
19450   int ret;
19451
19452   M (MPLS_FIB_DUMP, mp);
19453   S (mp);
19454
19455   /* Use a control ping for synchronization */
19456   MPING (CONTROL_PING, mp_ping);
19457   S (mp_ping);
19458
19459   W (ret);
19460   return ret;
19461 }
19462
19463 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19464 #define vl_api_ip_fib_details_t_print vl_noop_handler
19465
19466 static void
19467 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19468 {
19469   vat_main_t *vam = &vat_main;
19470   int count = ntohl (mp->count);
19471   vl_api_fib_path_t *fp;
19472   int i;
19473
19474   print (vam->ofp,
19475          "table-id %d, prefix %U/%d",
19476          ntohl (mp->table_id), format_ip4_address, mp->address,
19477          mp->address_length);
19478   fp = mp->path;
19479   for (i = 0; i < count; i++)
19480     {
19481       if (fp->afi == IP46_TYPE_IP6)
19482         print (vam->ofp,
19483                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19484                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19485                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19486                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19487                format_ip6_address, fp->next_hop);
19488       else if (fp->afi == IP46_TYPE_IP4)
19489         print (vam->ofp,
19490                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19491                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19492                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19493                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19494                format_ip4_address, fp->next_hop);
19495       fp++;
19496     }
19497 }
19498
19499 static void vl_api_ip_fib_details_t_handler_json
19500   (vl_api_ip_fib_details_t * mp)
19501 {
19502   vat_main_t *vam = &vat_main;
19503   int count = ntohl (mp->count);
19504   vat_json_node_t *node = NULL;
19505   struct in_addr ip4;
19506   struct in6_addr ip6;
19507   vl_api_fib_path_t *fp;
19508   int i;
19509
19510   if (VAT_JSON_ARRAY != vam->json_tree.type)
19511     {
19512       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19513       vat_json_init_array (&vam->json_tree);
19514     }
19515   node = vat_json_array_add (&vam->json_tree);
19516
19517   vat_json_init_object (node);
19518   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19519   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19520   vat_json_object_add_ip4 (node, "prefix", ip4);
19521   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19522   vat_json_object_add_uint (node, "path_count", count);
19523   fp = mp->path;
19524   for (i = 0; i < count; i++)
19525     {
19526       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19527       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19528       vat_json_object_add_uint (node, "is_local", fp->is_local);
19529       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19530       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19531       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19532       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19533       if (fp->afi == IP46_TYPE_IP4)
19534         {
19535           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19536           vat_json_object_add_ip4 (node, "next_hop", ip4);
19537         }
19538       else if (fp->afi == IP46_TYPE_IP6)
19539         {
19540           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19541           vat_json_object_add_ip6 (node, "next_hop", ip6);
19542         }
19543     }
19544 }
19545
19546 static int
19547 api_ip_fib_dump (vat_main_t * vam)
19548 {
19549   vl_api_ip_fib_dump_t *mp;
19550   vl_api_control_ping_t *mp_ping;
19551   int ret;
19552
19553   M (IP_FIB_DUMP, mp);
19554   S (mp);
19555
19556   /* Use a control ping for synchronization */
19557   MPING (CONTROL_PING, mp_ping);
19558   S (mp_ping);
19559
19560   W (ret);
19561   return ret;
19562 }
19563
19564 static int
19565 api_ip_mfib_dump (vat_main_t * vam)
19566 {
19567   vl_api_ip_mfib_dump_t *mp;
19568   vl_api_control_ping_t *mp_ping;
19569   int ret;
19570
19571   M (IP_MFIB_DUMP, mp);
19572   S (mp);
19573
19574   /* Use a control ping for synchronization */
19575   MPING (CONTROL_PING, mp_ping);
19576   S (mp_ping);
19577
19578   W (ret);
19579   return ret;
19580 }
19581
19582 static void vl_api_ip_neighbor_details_t_handler
19583   (vl_api_ip_neighbor_details_t * mp)
19584 {
19585   vat_main_t *vam = &vat_main;
19586
19587   print (vam->ofp, "%c %U %U",
19588          (mp->is_static) ? 'S' : 'D',
19589          format_ethernet_address, &mp->mac_address,
19590          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19591          &mp->ip_address);
19592 }
19593
19594 static void vl_api_ip_neighbor_details_t_handler_json
19595   (vl_api_ip_neighbor_details_t * mp)
19596 {
19597
19598   vat_main_t *vam = &vat_main;
19599   vat_json_node_t *node;
19600   struct in_addr ip4;
19601   struct in6_addr ip6;
19602
19603   if (VAT_JSON_ARRAY != vam->json_tree.type)
19604     {
19605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19606       vat_json_init_array (&vam->json_tree);
19607     }
19608   node = vat_json_array_add (&vam->json_tree);
19609
19610   vat_json_init_object (node);
19611   vat_json_object_add_string_copy (node, "flag",
19612                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19613                                    "dynamic");
19614
19615   vat_json_object_add_string_copy (node, "link_layer",
19616                                    format (0, "%U", format_ethernet_address,
19617                                            &mp->mac_address));
19618
19619   if (mp->is_ipv6)
19620     {
19621       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19622       vat_json_object_add_ip6 (node, "ip_address", ip6);
19623     }
19624   else
19625     {
19626       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19627       vat_json_object_add_ip4 (node, "ip_address", ip4);
19628     }
19629 }
19630
19631 static int
19632 api_ip_neighbor_dump (vat_main_t * vam)
19633 {
19634   unformat_input_t *i = vam->input;
19635   vl_api_ip_neighbor_dump_t *mp;
19636   vl_api_control_ping_t *mp_ping;
19637   u8 is_ipv6 = 0;
19638   u32 sw_if_index = ~0;
19639   int ret;
19640
19641   /* Parse args required to build the message */
19642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19643     {
19644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19645         ;
19646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19647         ;
19648       else if (unformat (i, "ip6"))
19649         is_ipv6 = 1;
19650       else
19651         break;
19652     }
19653
19654   if (sw_if_index == ~0)
19655     {
19656       errmsg ("missing interface name or sw_if_index");
19657       return -99;
19658     }
19659
19660   M (IP_NEIGHBOR_DUMP, mp);
19661   mp->is_ipv6 = (u8) is_ipv6;
19662   mp->sw_if_index = ntohl (sw_if_index);
19663   S (mp);
19664
19665   /* Use a control ping for synchronization */
19666   MPING (CONTROL_PING, mp_ping);
19667   S (mp_ping);
19668
19669   W (ret);
19670   return ret;
19671 }
19672
19673 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19674 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19675
19676 static void
19677 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19678 {
19679   vat_main_t *vam = &vat_main;
19680   int count = ntohl (mp->count);
19681   vl_api_fib_path_t *fp;
19682   int i;
19683
19684   print (vam->ofp,
19685          "table-id %d, prefix %U/%d",
19686          ntohl (mp->table_id), format_ip6_address, mp->address,
19687          mp->address_length);
19688   fp = mp->path;
19689   for (i = 0; i < count; i++)
19690     {
19691       if (fp->afi == IP46_TYPE_IP6)
19692         print (vam->ofp,
19693                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19694                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19695                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19696                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19697                format_ip6_address, fp->next_hop);
19698       else if (fp->afi == IP46_TYPE_IP4)
19699         print (vam->ofp,
19700                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19701                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19702                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19703                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19704                format_ip4_address, fp->next_hop);
19705       fp++;
19706     }
19707 }
19708
19709 static void vl_api_ip6_fib_details_t_handler_json
19710   (vl_api_ip6_fib_details_t * mp)
19711 {
19712   vat_main_t *vam = &vat_main;
19713   int count = ntohl (mp->count);
19714   vat_json_node_t *node = NULL;
19715   struct in_addr ip4;
19716   struct in6_addr ip6;
19717   vl_api_fib_path_t *fp;
19718   int i;
19719
19720   if (VAT_JSON_ARRAY != vam->json_tree.type)
19721     {
19722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19723       vat_json_init_array (&vam->json_tree);
19724     }
19725   node = vat_json_array_add (&vam->json_tree);
19726
19727   vat_json_init_object (node);
19728   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19729   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19730   vat_json_object_add_ip6 (node, "prefix", ip6);
19731   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19732   vat_json_object_add_uint (node, "path_count", count);
19733   fp = mp->path;
19734   for (i = 0; i < count; i++)
19735     {
19736       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19737       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19738       vat_json_object_add_uint (node, "is_local", fp->is_local);
19739       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19740       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19741       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19742       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19743       if (fp->afi == IP46_TYPE_IP4)
19744         {
19745           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19746           vat_json_object_add_ip4 (node, "next_hop", ip4);
19747         }
19748       else if (fp->afi == IP46_TYPE_IP6)
19749         {
19750           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19751           vat_json_object_add_ip6 (node, "next_hop", ip6);
19752         }
19753     }
19754 }
19755
19756 static int
19757 api_ip6_fib_dump (vat_main_t * vam)
19758 {
19759   vl_api_ip6_fib_dump_t *mp;
19760   vl_api_control_ping_t *mp_ping;
19761   int ret;
19762
19763   M (IP6_FIB_DUMP, mp);
19764   S (mp);
19765
19766   /* Use a control ping for synchronization */
19767   MPING (CONTROL_PING, mp_ping);
19768   S (mp_ping);
19769
19770   W (ret);
19771   return ret;
19772 }
19773
19774 static int
19775 api_ip6_mfib_dump (vat_main_t * vam)
19776 {
19777   vl_api_ip6_mfib_dump_t *mp;
19778   vl_api_control_ping_t *mp_ping;
19779   int ret;
19780
19781   M (IP6_MFIB_DUMP, mp);
19782   S (mp);
19783
19784   /* Use a control ping for synchronization */
19785   MPING (CONTROL_PING, mp_ping);
19786   S (mp_ping);
19787
19788   W (ret);
19789   return ret;
19790 }
19791
19792 int
19793 api_classify_table_ids (vat_main_t * vam)
19794 {
19795   vl_api_classify_table_ids_t *mp;
19796   int ret;
19797
19798   /* Construct the API message */
19799   M (CLASSIFY_TABLE_IDS, mp);
19800   mp->context = 0;
19801
19802   S (mp);
19803   W (ret);
19804   return ret;
19805 }
19806
19807 int
19808 api_classify_table_by_interface (vat_main_t * vam)
19809 {
19810   unformat_input_t *input = vam->input;
19811   vl_api_classify_table_by_interface_t *mp;
19812
19813   u32 sw_if_index = ~0;
19814   int ret;
19815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19816     {
19817       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19818         ;
19819       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19820         ;
19821       else
19822         break;
19823     }
19824   if (sw_if_index == ~0)
19825     {
19826       errmsg ("missing interface name or sw_if_index");
19827       return -99;
19828     }
19829
19830   /* Construct the API message */
19831   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19832   mp->context = 0;
19833   mp->sw_if_index = ntohl (sw_if_index);
19834
19835   S (mp);
19836   W (ret);
19837   return ret;
19838 }
19839
19840 int
19841 api_classify_table_info (vat_main_t * vam)
19842 {
19843   unformat_input_t *input = vam->input;
19844   vl_api_classify_table_info_t *mp;
19845
19846   u32 table_id = ~0;
19847   int ret;
19848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19849     {
19850       if (unformat (input, "table_id %d", &table_id))
19851         ;
19852       else
19853         break;
19854     }
19855   if (table_id == ~0)
19856     {
19857       errmsg ("missing table id");
19858       return -99;
19859     }
19860
19861   /* Construct the API message */
19862   M (CLASSIFY_TABLE_INFO, mp);
19863   mp->context = 0;
19864   mp->table_id = ntohl (table_id);
19865
19866   S (mp);
19867   W (ret);
19868   return ret;
19869 }
19870
19871 int
19872 api_classify_session_dump (vat_main_t * vam)
19873 {
19874   unformat_input_t *input = vam->input;
19875   vl_api_classify_session_dump_t *mp;
19876   vl_api_control_ping_t *mp_ping;
19877
19878   u32 table_id = ~0;
19879   int ret;
19880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19881     {
19882       if (unformat (input, "table_id %d", &table_id))
19883         ;
19884       else
19885         break;
19886     }
19887   if (table_id == ~0)
19888     {
19889       errmsg ("missing table id");
19890       return -99;
19891     }
19892
19893   /* Construct the API message */
19894   M (CLASSIFY_SESSION_DUMP, mp);
19895   mp->context = 0;
19896   mp->table_id = ntohl (table_id);
19897   S (mp);
19898
19899   /* Use a control ping for synchronization */
19900   MPING (CONTROL_PING, mp_ping);
19901   S (mp_ping);
19902
19903   W (ret);
19904   return ret;
19905 }
19906
19907 static void
19908 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19909 {
19910   vat_main_t *vam = &vat_main;
19911
19912   print (vam->ofp, "collector_address %U, collector_port %d, "
19913          "src_address %U, vrf_id %d, path_mtu %u, "
19914          "template_interval %u, udp_checksum %d",
19915          format_ip4_address, mp->collector_address,
19916          ntohs (mp->collector_port),
19917          format_ip4_address, mp->src_address,
19918          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19919          ntohl (mp->template_interval), mp->udp_checksum);
19920
19921   vam->retval = 0;
19922   vam->result_ready = 1;
19923 }
19924
19925 static void
19926   vl_api_ipfix_exporter_details_t_handler_json
19927   (vl_api_ipfix_exporter_details_t * mp)
19928 {
19929   vat_main_t *vam = &vat_main;
19930   vat_json_node_t node;
19931   struct in_addr collector_address;
19932   struct in_addr src_address;
19933
19934   vat_json_init_object (&node);
19935   clib_memcpy (&collector_address, &mp->collector_address,
19936                sizeof (collector_address));
19937   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19938   vat_json_object_add_uint (&node, "collector_port",
19939                             ntohs (mp->collector_port));
19940   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19941   vat_json_object_add_ip4 (&node, "src_address", src_address);
19942   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19943   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19944   vat_json_object_add_uint (&node, "template_interval",
19945                             ntohl (mp->template_interval));
19946   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19947
19948   vat_json_print (vam->ofp, &node);
19949   vat_json_free (&node);
19950   vam->retval = 0;
19951   vam->result_ready = 1;
19952 }
19953
19954 int
19955 api_ipfix_exporter_dump (vat_main_t * vam)
19956 {
19957   vl_api_ipfix_exporter_dump_t *mp;
19958   int ret;
19959
19960   /* Construct the API message */
19961   M (IPFIX_EXPORTER_DUMP, mp);
19962   mp->context = 0;
19963
19964   S (mp);
19965   W (ret);
19966   return ret;
19967 }
19968
19969 static int
19970 api_ipfix_classify_stream_dump (vat_main_t * vam)
19971 {
19972   vl_api_ipfix_classify_stream_dump_t *mp;
19973   int ret;
19974
19975   /* Construct the API message */
19976   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19977   mp->context = 0;
19978
19979   S (mp);
19980   W (ret);
19981   return ret;
19982   /* NOTREACHED */
19983   return 0;
19984 }
19985
19986 static void
19987   vl_api_ipfix_classify_stream_details_t_handler
19988   (vl_api_ipfix_classify_stream_details_t * mp)
19989 {
19990   vat_main_t *vam = &vat_main;
19991   print (vam->ofp, "domain_id %d, src_port %d",
19992          ntohl (mp->domain_id), ntohs (mp->src_port));
19993   vam->retval = 0;
19994   vam->result_ready = 1;
19995 }
19996
19997 static void
19998   vl_api_ipfix_classify_stream_details_t_handler_json
19999   (vl_api_ipfix_classify_stream_details_t * mp)
20000 {
20001   vat_main_t *vam = &vat_main;
20002   vat_json_node_t node;
20003
20004   vat_json_init_object (&node);
20005   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20006   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20007
20008   vat_json_print (vam->ofp, &node);
20009   vat_json_free (&node);
20010   vam->retval = 0;
20011   vam->result_ready = 1;
20012 }
20013
20014 static int
20015 api_ipfix_classify_table_dump (vat_main_t * vam)
20016 {
20017   vl_api_ipfix_classify_table_dump_t *mp;
20018   vl_api_control_ping_t *mp_ping;
20019   int ret;
20020
20021   if (!vam->json_output)
20022     {
20023       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20024              "transport_protocol");
20025     }
20026
20027   /* Construct the API message */
20028   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20029
20030   /* send it... */
20031   S (mp);
20032
20033   /* Use a control ping for synchronization */
20034   MPING (CONTROL_PING, mp_ping);
20035   S (mp_ping);
20036
20037   W (ret);
20038   return ret;
20039 }
20040
20041 static void
20042   vl_api_ipfix_classify_table_details_t_handler
20043   (vl_api_ipfix_classify_table_details_t * mp)
20044 {
20045   vat_main_t *vam = &vat_main;
20046   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20047          mp->transport_protocol);
20048 }
20049
20050 static void
20051   vl_api_ipfix_classify_table_details_t_handler_json
20052   (vl_api_ipfix_classify_table_details_t * mp)
20053 {
20054   vat_json_node_t *node = NULL;
20055   vat_main_t *vam = &vat_main;
20056
20057   if (VAT_JSON_ARRAY != vam->json_tree.type)
20058     {
20059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20060       vat_json_init_array (&vam->json_tree);
20061     }
20062
20063   node = vat_json_array_add (&vam->json_tree);
20064   vat_json_init_object (node);
20065
20066   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20067   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20068   vat_json_object_add_uint (node, "transport_protocol",
20069                             mp->transport_protocol);
20070 }
20071
20072 static int
20073 api_sw_interface_span_enable_disable (vat_main_t * vam)
20074 {
20075   unformat_input_t *i = vam->input;
20076   vl_api_sw_interface_span_enable_disable_t *mp;
20077   u32 src_sw_if_index = ~0;
20078   u32 dst_sw_if_index = ~0;
20079   u8 state = 3;
20080   int ret;
20081   u8 is_l2 = 0;
20082
20083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat
20086           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20087         ;
20088       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20089         ;
20090       else
20091         if (unformat
20092             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20093         ;
20094       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20095         ;
20096       else if (unformat (i, "disable"))
20097         state = 0;
20098       else if (unformat (i, "rx"))
20099         state = 1;
20100       else if (unformat (i, "tx"))
20101         state = 2;
20102       else if (unformat (i, "both"))
20103         state = 3;
20104       else if (unformat (i, "l2"))
20105         is_l2 = 1;
20106       else
20107         break;
20108     }
20109
20110   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20111
20112   mp->sw_if_index_from = htonl (src_sw_if_index);
20113   mp->sw_if_index_to = htonl (dst_sw_if_index);
20114   mp->state = state;
20115   mp->is_l2 = is_l2;
20116
20117   S (mp);
20118   W (ret);
20119   return ret;
20120 }
20121
20122 static void
20123 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20124                                             * mp)
20125 {
20126   vat_main_t *vam = &vat_main;
20127   u8 *sw_if_from_name = 0;
20128   u8 *sw_if_to_name = 0;
20129   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20130   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20131   char *states[] = { "none", "rx", "tx", "both" };
20132   hash_pair_t *p;
20133
20134   /* *INDENT-OFF* */
20135   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20136   ({
20137     if ((u32) p->value[0] == sw_if_index_from)
20138       {
20139         sw_if_from_name = (u8 *)(p->key);
20140         if (sw_if_to_name)
20141           break;
20142       }
20143     if ((u32) p->value[0] == sw_if_index_to)
20144       {
20145         sw_if_to_name = (u8 *)(p->key);
20146         if (sw_if_from_name)
20147           break;
20148       }
20149   }));
20150   /* *INDENT-ON* */
20151   print (vam->ofp, "%20s => %20s (%s)",
20152          sw_if_from_name, sw_if_to_name, states[mp->state]);
20153 }
20154
20155 static void
20156   vl_api_sw_interface_span_details_t_handler_json
20157   (vl_api_sw_interface_span_details_t * mp)
20158 {
20159   vat_main_t *vam = &vat_main;
20160   vat_json_node_t *node = NULL;
20161   u8 *sw_if_from_name = 0;
20162   u8 *sw_if_to_name = 0;
20163   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20164   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20165   hash_pair_t *p;
20166
20167   /* *INDENT-OFF* */
20168   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20169   ({
20170     if ((u32) p->value[0] == sw_if_index_from)
20171       {
20172         sw_if_from_name = (u8 *)(p->key);
20173         if (sw_if_to_name)
20174           break;
20175       }
20176     if ((u32) p->value[0] == sw_if_index_to)
20177       {
20178         sw_if_to_name = (u8 *)(p->key);
20179         if (sw_if_from_name)
20180           break;
20181       }
20182   }));
20183   /* *INDENT-ON* */
20184
20185   if (VAT_JSON_ARRAY != vam->json_tree.type)
20186     {
20187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20188       vat_json_init_array (&vam->json_tree);
20189     }
20190   node = vat_json_array_add (&vam->json_tree);
20191
20192   vat_json_init_object (node);
20193   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20194   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20195   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20196   if (0 != sw_if_to_name)
20197     {
20198       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20199     }
20200   vat_json_object_add_uint (node, "state", mp->state);
20201 }
20202
20203 static int
20204 api_sw_interface_span_dump (vat_main_t * vam)
20205 {
20206   unformat_input_t *input = vam->input;
20207   vl_api_sw_interface_span_dump_t *mp;
20208   vl_api_control_ping_t *mp_ping;
20209   u8 is_l2 = 0;
20210   int ret;
20211
20212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20213     {
20214       if (unformat (input, "l2"))
20215         is_l2 = 1;
20216       else
20217         break;
20218     }
20219
20220   M (SW_INTERFACE_SPAN_DUMP, mp);
20221   mp->is_l2 = is_l2;
20222   S (mp);
20223
20224   /* Use a control ping for synchronization */
20225   MPING (CONTROL_PING, mp_ping);
20226   S (mp_ping);
20227
20228   W (ret);
20229   return ret;
20230 }
20231
20232 int
20233 api_pg_create_interface (vat_main_t * vam)
20234 {
20235   unformat_input_t *input = vam->input;
20236   vl_api_pg_create_interface_t *mp;
20237
20238   u32 if_id = ~0;
20239   int ret;
20240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20241     {
20242       if (unformat (input, "if_id %d", &if_id))
20243         ;
20244       else
20245         break;
20246     }
20247   if (if_id == ~0)
20248     {
20249       errmsg ("missing pg interface index");
20250       return -99;
20251     }
20252
20253   /* Construct the API message */
20254   M (PG_CREATE_INTERFACE, mp);
20255   mp->context = 0;
20256   mp->interface_id = ntohl (if_id);
20257
20258   S (mp);
20259   W (ret);
20260   return ret;
20261 }
20262
20263 int
20264 api_pg_capture (vat_main_t * vam)
20265 {
20266   unformat_input_t *input = vam->input;
20267   vl_api_pg_capture_t *mp;
20268
20269   u32 if_id = ~0;
20270   u8 enable = 1;
20271   u32 count = 1;
20272   u8 pcap_file_set = 0;
20273   u8 *pcap_file = 0;
20274   int ret;
20275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20276     {
20277       if (unformat (input, "if_id %d", &if_id))
20278         ;
20279       else if (unformat (input, "pcap %s", &pcap_file))
20280         pcap_file_set = 1;
20281       else if (unformat (input, "count %d", &count))
20282         ;
20283       else if (unformat (input, "disable"))
20284         enable = 0;
20285       else
20286         break;
20287     }
20288   if (if_id == ~0)
20289     {
20290       errmsg ("missing pg interface index");
20291       return -99;
20292     }
20293   if (pcap_file_set > 0)
20294     {
20295       if (vec_len (pcap_file) > 255)
20296         {
20297           errmsg ("pcap file name is too long");
20298           return -99;
20299         }
20300     }
20301
20302   u32 name_len = vec_len (pcap_file);
20303   /* Construct the API message */
20304   M (PG_CAPTURE, mp);
20305   mp->context = 0;
20306   mp->interface_id = ntohl (if_id);
20307   mp->is_enabled = enable;
20308   mp->count = ntohl (count);
20309   mp->pcap_name_length = ntohl (name_len);
20310   if (pcap_file_set != 0)
20311     {
20312       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20313     }
20314   vec_free (pcap_file);
20315
20316   S (mp);
20317   W (ret);
20318   return ret;
20319 }
20320
20321 int
20322 api_pg_enable_disable (vat_main_t * vam)
20323 {
20324   unformat_input_t *input = vam->input;
20325   vl_api_pg_enable_disable_t *mp;
20326
20327   u8 enable = 1;
20328   u8 stream_name_set = 0;
20329   u8 *stream_name = 0;
20330   int ret;
20331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20332     {
20333       if (unformat (input, "stream %s", &stream_name))
20334         stream_name_set = 1;
20335       else if (unformat (input, "disable"))
20336         enable = 0;
20337       else
20338         break;
20339     }
20340
20341   if (stream_name_set > 0)
20342     {
20343       if (vec_len (stream_name) > 255)
20344         {
20345           errmsg ("stream name too long");
20346           return -99;
20347         }
20348     }
20349
20350   u32 name_len = vec_len (stream_name);
20351   /* Construct the API message */
20352   M (PG_ENABLE_DISABLE, mp);
20353   mp->context = 0;
20354   mp->is_enabled = enable;
20355   if (stream_name_set != 0)
20356     {
20357       mp->stream_name_length = ntohl (name_len);
20358       clib_memcpy (mp->stream_name, stream_name, name_len);
20359     }
20360   vec_free (stream_name);
20361
20362   S (mp);
20363   W (ret);
20364   return ret;
20365 }
20366
20367 int
20368 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20369 {
20370   unformat_input_t *input = vam->input;
20371   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20372
20373   u16 *low_ports = 0;
20374   u16 *high_ports = 0;
20375   u16 this_low;
20376   u16 this_hi;
20377   ip4_address_t ip4_addr;
20378   ip6_address_t ip6_addr;
20379   u32 length;
20380   u32 tmp, tmp2;
20381   u8 prefix_set = 0;
20382   u32 vrf_id = ~0;
20383   u8 is_add = 1;
20384   u8 is_ipv6 = 0;
20385   int ret;
20386
20387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20388     {
20389       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20390         {
20391           prefix_set = 1;
20392         }
20393       else
20394         if (unformat
20395             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20396         {
20397           prefix_set = 1;
20398           is_ipv6 = 1;
20399         }
20400       else if (unformat (input, "vrf %d", &vrf_id))
20401         ;
20402       else if (unformat (input, "del"))
20403         is_add = 0;
20404       else if (unformat (input, "port %d", &tmp))
20405         {
20406           if (tmp == 0 || tmp > 65535)
20407             {
20408               errmsg ("port %d out of range", tmp);
20409               return -99;
20410             }
20411           this_low = tmp;
20412           this_hi = this_low + 1;
20413           vec_add1 (low_ports, this_low);
20414           vec_add1 (high_ports, this_hi);
20415         }
20416       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20417         {
20418           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20419             {
20420               errmsg ("incorrect range parameters");
20421               return -99;
20422             }
20423           this_low = tmp;
20424           /* Note: in debug CLI +1 is added to high before
20425              passing to real fn that does "the work"
20426              (ip_source_and_port_range_check_add_del).
20427              This fn is a wrapper around the binary API fn a
20428              control plane will call, which expects this increment
20429              to have occurred. Hence letting the binary API control
20430              plane fn do the increment for consistency between VAT
20431              and other control planes.
20432            */
20433           this_hi = tmp2;
20434           vec_add1 (low_ports, this_low);
20435           vec_add1 (high_ports, this_hi);
20436         }
20437       else
20438         break;
20439     }
20440
20441   if (prefix_set == 0)
20442     {
20443       errmsg ("<address>/<mask> not specified");
20444       return -99;
20445     }
20446
20447   if (vrf_id == ~0)
20448     {
20449       errmsg ("VRF ID required, not specified");
20450       return -99;
20451     }
20452
20453   if (vrf_id == 0)
20454     {
20455       errmsg
20456         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20457       return -99;
20458     }
20459
20460   if (vec_len (low_ports) == 0)
20461     {
20462       errmsg ("At least one port or port range required");
20463       return -99;
20464     }
20465
20466   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20467
20468   mp->is_add = is_add;
20469
20470   if (is_ipv6)
20471     {
20472       mp->is_ipv6 = 1;
20473       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20474     }
20475   else
20476     {
20477       mp->is_ipv6 = 0;
20478       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20479     }
20480
20481   mp->mask_length = length;
20482   mp->number_of_ranges = vec_len (low_ports);
20483
20484   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20485   vec_free (low_ports);
20486
20487   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20488   vec_free (high_ports);
20489
20490   mp->vrf_id = ntohl (vrf_id);
20491
20492   S (mp);
20493   W (ret);
20494   return ret;
20495 }
20496
20497 int
20498 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20499 {
20500   unformat_input_t *input = vam->input;
20501   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20502   u32 sw_if_index = ~0;
20503   int vrf_set = 0;
20504   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20505   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20506   u8 is_add = 1;
20507   int ret;
20508
20509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20510     {
20511       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20512         ;
20513       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20514         ;
20515       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20516         vrf_set = 1;
20517       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20518         vrf_set = 1;
20519       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20520         vrf_set = 1;
20521       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20522         vrf_set = 1;
20523       else if (unformat (input, "del"))
20524         is_add = 0;
20525       else
20526         break;
20527     }
20528
20529   if (sw_if_index == ~0)
20530     {
20531       errmsg ("Interface required but not specified");
20532       return -99;
20533     }
20534
20535   if (vrf_set == 0)
20536     {
20537       errmsg ("VRF ID required but not specified");
20538       return -99;
20539     }
20540
20541   if (tcp_out_vrf_id == 0
20542       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20543     {
20544       errmsg
20545         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20546       return -99;
20547     }
20548
20549   /* Construct the API message */
20550   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20551
20552   mp->sw_if_index = ntohl (sw_if_index);
20553   mp->is_add = is_add;
20554   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20555   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20556   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20557   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20558
20559   /* send it... */
20560   S (mp);
20561
20562   /* Wait for a reply... */
20563   W (ret);
20564   return ret;
20565 }
20566
20567 static int
20568 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20569 {
20570   unformat_input_t *i = vam->input;
20571   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20572   u32 local_sa_id = 0;
20573   u32 remote_sa_id = 0;
20574   ip4_address_t src_address;
20575   ip4_address_t dst_address;
20576   u8 is_add = 1;
20577   int ret;
20578
20579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20580     {
20581       if (unformat (i, "local_sa %d", &local_sa_id))
20582         ;
20583       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20584         ;
20585       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20586         ;
20587       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20588         ;
20589       else if (unformat (i, "del"))
20590         is_add = 0;
20591       else
20592         {
20593           clib_warning ("parse error '%U'", format_unformat_error, i);
20594           return -99;
20595         }
20596     }
20597
20598   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20599
20600   mp->local_sa_id = ntohl (local_sa_id);
20601   mp->remote_sa_id = ntohl (remote_sa_id);
20602   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20603   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20604   mp->is_add = is_add;
20605
20606   S (mp);
20607   W (ret);
20608   return ret;
20609 }
20610
20611 static int
20612 api_punt (vat_main_t * vam)
20613 {
20614   unformat_input_t *i = vam->input;
20615   vl_api_punt_t *mp;
20616   u32 ipv = ~0;
20617   u32 protocol = ~0;
20618   u32 port = ~0;
20619   int is_add = 1;
20620   int ret;
20621
20622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20623     {
20624       if (unformat (i, "ip %d", &ipv))
20625         ;
20626       else if (unformat (i, "protocol %d", &protocol))
20627         ;
20628       else if (unformat (i, "port %d", &port))
20629         ;
20630       else if (unformat (i, "del"))
20631         is_add = 0;
20632       else
20633         {
20634           clib_warning ("parse error '%U'", format_unformat_error, i);
20635           return -99;
20636         }
20637     }
20638
20639   M (PUNT, mp);
20640
20641   mp->is_add = (u8) is_add;
20642   mp->ipv = (u8) ipv;
20643   mp->l4_protocol = (u8) protocol;
20644   mp->l4_port = htons ((u16) port);
20645
20646   S (mp);
20647   W (ret);
20648   return ret;
20649 }
20650
20651 static void vl_api_ipsec_gre_tunnel_details_t_handler
20652   (vl_api_ipsec_gre_tunnel_details_t * mp)
20653 {
20654   vat_main_t *vam = &vat_main;
20655
20656   print (vam->ofp, "%11d%15U%15U%14d%14d",
20657          ntohl (mp->sw_if_index),
20658          format_ip4_address, &mp->src_address,
20659          format_ip4_address, &mp->dst_address,
20660          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20661 }
20662
20663 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20664   (vl_api_ipsec_gre_tunnel_details_t * mp)
20665 {
20666   vat_main_t *vam = &vat_main;
20667   vat_json_node_t *node = NULL;
20668   struct in_addr ip4;
20669
20670   if (VAT_JSON_ARRAY != vam->json_tree.type)
20671     {
20672       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20673       vat_json_init_array (&vam->json_tree);
20674     }
20675   node = vat_json_array_add (&vam->json_tree);
20676
20677   vat_json_init_object (node);
20678   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20679   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20680   vat_json_object_add_ip4 (node, "src_address", ip4);
20681   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20682   vat_json_object_add_ip4 (node, "dst_address", ip4);
20683   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20684   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20685 }
20686
20687 static int
20688 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20689 {
20690   unformat_input_t *i = vam->input;
20691   vl_api_ipsec_gre_tunnel_dump_t *mp;
20692   vl_api_control_ping_t *mp_ping;
20693   u32 sw_if_index;
20694   u8 sw_if_index_set = 0;
20695   int ret;
20696
20697   /* Parse args required to build the message */
20698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20699     {
20700       if (unformat (i, "sw_if_index %d", &sw_if_index))
20701         sw_if_index_set = 1;
20702       else
20703         break;
20704     }
20705
20706   if (sw_if_index_set == 0)
20707     {
20708       sw_if_index = ~0;
20709     }
20710
20711   if (!vam->json_output)
20712     {
20713       print (vam->ofp, "%11s%15s%15s%14s%14s",
20714              "sw_if_index", "src_address", "dst_address",
20715              "local_sa_id", "remote_sa_id");
20716     }
20717
20718   /* Get list of gre-tunnel interfaces */
20719   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20720
20721   mp->sw_if_index = htonl (sw_if_index);
20722
20723   S (mp);
20724
20725   /* Use a control ping for synchronization */
20726   MPING (CONTROL_PING, mp_ping);
20727   S (mp_ping);
20728
20729   W (ret);
20730   return ret;
20731 }
20732
20733 static int
20734 api_delete_subif (vat_main_t * vam)
20735 {
20736   unformat_input_t *i = vam->input;
20737   vl_api_delete_subif_t *mp;
20738   u32 sw_if_index = ~0;
20739   int ret;
20740
20741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20742     {
20743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20744         ;
20745       if (unformat (i, "sw_if_index %d", &sw_if_index))
20746         ;
20747       else
20748         break;
20749     }
20750
20751   if (sw_if_index == ~0)
20752     {
20753       errmsg ("missing sw_if_index");
20754       return -99;
20755     }
20756
20757   /* Construct the API message */
20758   M (DELETE_SUBIF, mp);
20759   mp->sw_if_index = ntohl (sw_if_index);
20760
20761   S (mp);
20762   W (ret);
20763   return ret;
20764 }
20765
20766 #define foreach_pbb_vtr_op      \
20767 _("disable",  L2_VTR_DISABLED)  \
20768 _("pop",  L2_VTR_POP_2)         \
20769 _("push",  L2_VTR_PUSH_2)
20770
20771 static int
20772 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20773 {
20774   unformat_input_t *i = vam->input;
20775   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20776   u32 sw_if_index = ~0, vtr_op = ~0;
20777   u16 outer_tag = ~0;
20778   u8 dmac[6], smac[6];
20779   u8 dmac_set = 0, smac_set = 0;
20780   u16 vlanid = 0;
20781   u32 sid = ~0;
20782   u32 tmp;
20783   int ret;
20784
20785   /* Shut up coverity */
20786   memset (dmac, 0, sizeof (dmac));
20787   memset (smac, 0, sizeof (smac));
20788
20789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20790     {
20791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20792         ;
20793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20794         ;
20795       else if (unformat (i, "vtr_op %d", &vtr_op))
20796         ;
20797 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20798       foreach_pbb_vtr_op
20799 #undef _
20800         else if (unformat (i, "translate_pbb_stag"))
20801         {
20802           if (unformat (i, "%d", &tmp))
20803             {
20804               vtr_op = L2_VTR_TRANSLATE_2_1;
20805               outer_tag = tmp;
20806             }
20807           else
20808             {
20809               errmsg
20810                 ("translate_pbb_stag operation requires outer tag definition");
20811               return -99;
20812             }
20813         }
20814       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20815         dmac_set++;
20816       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20817         smac_set++;
20818       else if (unformat (i, "sid %d", &sid))
20819         ;
20820       else if (unformat (i, "vlanid %d", &tmp))
20821         vlanid = tmp;
20822       else
20823         {
20824           clib_warning ("parse error '%U'", format_unformat_error, i);
20825           return -99;
20826         }
20827     }
20828
20829   if ((sw_if_index == ~0) || (vtr_op == ~0))
20830     {
20831       errmsg ("missing sw_if_index or vtr operation");
20832       return -99;
20833     }
20834   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20835       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20836     {
20837       errmsg
20838         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20839       return -99;
20840     }
20841
20842   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20843   mp->sw_if_index = ntohl (sw_if_index);
20844   mp->vtr_op = ntohl (vtr_op);
20845   mp->outer_tag = ntohs (outer_tag);
20846   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20847   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20848   mp->b_vlanid = ntohs (vlanid);
20849   mp->i_sid = ntohl (sid);
20850
20851   S (mp);
20852   W (ret);
20853   return ret;
20854 }
20855
20856 static int
20857 api_flow_classify_set_interface (vat_main_t * vam)
20858 {
20859   unformat_input_t *i = vam->input;
20860   vl_api_flow_classify_set_interface_t *mp;
20861   u32 sw_if_index;
20862   int sw_if_index_set;
20863   u32 ip4_table_index = ~0;
20864   u32 ip6_table_index = ~0;
20865   u8 is_add = 1;
20866   int ret;
20867
20868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20869     {
20870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20871         sw_if_index_set = 1;
20872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20873         sw_if_index_set = 1;
20874       else if (unformat (i, "del"))
20875         is_add = 0;
20876       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20877         ;
20878       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20879         ;
20880       else
20881         {
20882           clib_warning ("parse error '%U'", format_unformat_error, i);
20883           return -99;
20884         }
20885     }
20886
20887   if (sw_if_index_set == 0)
20888     {
20889       errmsg ("missing interface name or sw_if_index");
20890       return -99;
20891     }
20892
20893   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20894
20895   mp->sw_if_index = ntohl (sw_if_index);
20896   mp->ip4_table_index = ntohl (ip4_table_index);
20897   mp->ip6_table_index = ntohl (ip6_table_index);
20898   mp->is_add = is_add;
20899
20900   S (mp);
20901   W (ret);
20902   return ret;
20903 }
20904
20905 static int
20906 api_flow_classify_dump (vat_main_t * vam)
20907 {
20908   unformat_input_t *i = vam->input;
20909   vl_api_flow_classify_dump_t *mp;
20910   vl_api_control_ping_t *mp_ping;
20911   u8 type = FLOW_CLASSIFY_N_TABLES;
20912   int ret;
20913
20914   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20915     ;
20916   else
20917     {
20918       errmsg ("classify table type must be specified");
20919       return -99;
20920     }
20921
20922   if (!vam->json_output)
20923     {
20924       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20925     }
20926
20927   M (FLOW_CLASSIFY_DUMP, mp);
20928   mp->type = type;
20929   /* send it... */
20930   S (mp);
20931
20932   /* Use a control ping for synchronization */
20933   MPING (CONTROL_PING, mp_ping);
20934   S (mp_ping);
20935
20936   /* Wait for a reply... */
20937   W (ret);
20938   return ret;
20939 }
20940
20941 static int
20942 api_feature_enable_disable (vat_main_t * vam)
20943 {
20944   unformat_input_t *i = vam->input;
20945   vl_api_feature_enable_disable_t *mp;
20946   u8 *arc_name = 0;
20947   u8 *feature_name = 0;
20948   u32 sw_if_index = ~0;
20949   u8 enable = 1;
20950   int ret;
20951
20952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20953     {
20954       if (unformat (i, "arc_name %s", &arc_name))
20955         ;
20956       else if (unformat (i, "feature_name %s", &feature_name))
20957         ;
20958       else
20959         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20960         ;
20961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20962         ;
20963       else if (unformat (i, "disable"))
20964         enable = 0;
20965       else
20966         break;
20967     }
20968
20969   if (arc_name == 0)
20970     {
20971       errmsg ("missing arc name");
20972       return -99;
20973     }
20974   if (vec_len (arc_name) > 63)
20975     {
20976       errmsg ("arc name too long");
20977     }
20978
20979   if (feature_name == 0)
20980     {
20981       errmsg ("missing feature name");
20982       return -99;
20983     }
20984   if (vec_len (feature_name) > 63)
20985     {
20986       errmsg ("feature name too long");
20987     }
20988
20989   if (sw_if_index == ~0)
20990     {
20991       errmsg ("missing interface name or sw_if_index");
20992       return -99;
20993     }
20994
20995   /* Construct the API message */
20996   M (FEATURE_ENABLE_DISABLE, mp);
20997   mp->sw_if_index = ntohl (sw_if_index);
20998   mp->enable = enable;
20999   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21000   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21001   vec_free (arc_name);
21002   vec_free (feature_name);
21003
21004   S (mp);
21005   W (ret);
21006   return ret;
21007 }
21008
21009 static int
21010 api_sw_interface_tag_add_del (vat_main_t * vam)
21011 {
21012   unformat_input_t *i = vam->input;
21013   vl_api_sw_interface_tag_add_del_t *mp;
21014   u32 sw_if_index = ~0;
21015   u8 *tag = 0;
21016   u8 enable = 1;
21017   int ret;
21018
21019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21020     {
21021       if (unformat (i, "tag %s", &tag))
21022         ;
21023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21024         ;
21025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21026         ;
21027       else if (unformat (i, "del"))
21028         enable = 0;
21029       else
21030         break;
21031     }
21032
21033   if (sw_if_index == ~0)
21034     {
21035       errmsg ("missing interface name or sw_if_index");
21036       return -99;
21037     }
21038
21039   if (enable && (tag == 0))
21040     {
21041       errmsg ("no tag specified");
21042       return -99;
21043     }
21044
21045   /* Construct the API message */
21046   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21047   mp->sw_if_index = ntohl (sw_if_index);
21048   mp->is_add = enable;
21049   if (enable)
21050     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21051   vec_free (tag);
21052
21053   S (mp);
21054   W (ret);
21055   return ret;
21056 }
21057
21058 static void vl_api_l2_xconnect_details_t_handler
21059   (vl_api_l2_xconnect_details_t * mp)
21060 {
21061   vat_main_t *vam = &vat_main;
21062
21063   print (vam->ofp, "%15d%15d",
21064          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21065 }
21066
21067 static void vl_api_l2_xconnect_details_t_handler_json
21068   (vl_api_l2_xconnect_details_t * mp)
21069 {
21070   vat_main_t *vam = &vat_main;
21071   vat_json_node_t *node = NULL;
21072
21073   if (VAT_JSON_ARRAY != vam->json_tree.type)
21074     {
21075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21076       vat_json_init_array (&vam->json_tree);
21077     }
21078   node = vat_json_array_add (&vam->json_tree);
21079
21080   vat_json_init_object (node);
21081   vat_json_object_add_uint (node, "rx_sw_if_index",
21082                             ntohl (mp->rx_sw_if_index));
21083   vat_json_object_add_uint (node, "tx_sw_if_index",
21084                             ntohl (mp->tx_sw_if_index));
21085 }
21086
21087 static int
21088 api_l2_xconnect_dump (vat_main_t * vam)
21089 {
21090   vl_api_l2_xconnect_dump_t *mp;
21091   vl_api_control_ping_t *mp_ping;
21092   int ret;
21093
21094   if (!vam->json_output)
21095     {
21096       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21097     }
21098
21099   M (L2_XCONNECT_DUMP, mp);
21100
21101   S (mp);
21102
21103   /* Use a control ping for synchronization */
21104   MPING (CONTROL_PING, mp_ping);
21105   S (mp_ping);
21106
21107   W (ret);
21108   return ret;
21109 }
21110
21111 static int
21112 api_sw_interface_set_mtu (vat_main_t * vam)
21113 {
21114   unformat_input_t *i = vam->input;
21115   vl_api_sw_interface_set_mtu_t *mp;
21116   u32 sw_if_index = ~0;
21117   u32 mtu = 0;
21118   int ret;
21119
21120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21121     {
21122       if (unformat (i, "mtu %d", &mtu))
21123         ;
21124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21125         ;
21126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21127         ;
21128       else
21129         break;
21130     }
21131
21132   if (sw_if_index == ~0)
21133     {
21134       errmsg ("missing interface name or sw_if_index");
21135       return -99;
21136     }
21137
21138   if (mtu == 0)
21139     {
21140       errmsg ("no mtu specified");
21141       return -99;
21142     }
21143
21144   /* Construct the API message */
21145   M (SW_INTERFACE_SET_MTU, mp);
21146   mp->sw_if_index = ntohl (sw_if_index);
21147   mp->mtu = ntohs ((u16) mtu);
21148
21149   S (mp);
21150   W (ret);
21151   return ret;
21152 }
21153
21154 static int
21155 api_p2p_ethernet_add (vat_main_t * vam)
21156 {
21157   unformat_input_t *i = vam->input;
21158   vl_api_p2p_ethernet_add_t *mp;
21159   u32 parent_if_index = ~0;
21160   u32 sub_id = ~0;
21161   u8 remote_mac[6];
21162   u8 mac_set = 0;
21163   int ret;
21164
21165   memset (remote_mac, 0, sizeof (remote_mac));
21166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21167     {
21168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21169         ;
21170       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21171         ;
21172       else
21173         if (unformat
21174             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21175         mac_set++;
21176       else if (unformat (i, "sub_id %d", &sub_id))
21177         ;
21178       else
21179         {
21180           clib_warning ("parse error '%U'", format_unformat_error, i);
21181           return -99;
21182         }
21183     }
21184
21185   if (parent_if_index == ~0)
21186     {
21187       errmsg ("missing interface name or sw_if_index");
21188       return -99;
21189     }
21190   if (mac_set == 0)
21191     {
21192       errmsg ("missing remote mac address");
21193       return -99;
21194     }
21195   if (sub_id == ~0)
21196     {
21197       errmsg ("missing sub-interface id");
21198       return -99;
21199     }
21200
21201   M (P2P_ETHERNET_ADD, mp);
21202   mp->parent_if_index = ntohl (parent_if_index);
21203   mp->subif_id = ntohl (sub_id);
21204   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21205
21206   S (mp);
21207   W (ret);
21208   return ret;
21209 }
21210
21211 static int
21212 api_p2p_ethernet_del (vat_main_t * vam)
21213 {
21214   unformat_input_t *i = vam->input;
21215   vl_api_p2p_ethernet_del_t *mp;
21216   u32 parent_if_index = ~0;
21217   u8 remote_mac[6];
21218   u8 mac_set = 0;
21219   int ret;
21220
21221   memset (remote_mac, 0, sizeof (remote_mac));
21222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21223     {
21224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21225         ;
21226       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21227         ;
21228       else
21229         if (unformat
21230             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21231         mac_set++;
21232       else
21233         {
21234           clib_warning ("parse error '%U'", format_unformat_error, i);
21235           return -99;
21236         }
21237     }
21238
21239   if (parent_if_index == ~0)
21240     {
21241       errmsg ("missing interface name or sw_if_index");
21242       return -99;
21243     }
21244   if (mac_set == 0)
21245     {
21246       errmsg ("missing remote mac address");
21247       return -99;
21248     }
21249
21250   M (P2P_ETHERNET_DEL, mp);
21251   mp->parent_if_index = ntohl (parent_if_index);
21252   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21253
21254   S (mp);
21255   W (ret);
21256   return ret;
21257 }
21258
21259 static int
21260 api_lldp_config (vat_main_t * vam)
21261 {
21262   unformat_input_t *i = vam->input;
21263   vl_api_lldp_config_t *mp;
21264   int tx_hold = 0;
21265   int tx_interval = 0;
21266   u8 *sys_name = NULL;
21267   int ret;
21268
21269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21270     {
21271       if (unformat (i, "system-name %s", &sys_name))
21272         ;
21273       else if (unformat (i, "tx-hold %d", &tx_hold))
21274         ;
21275       else if (unformat (i, "tx-interval %d", &tx_interval))
21276         ;
21277       else
21278         {
21279           clib_warning ("parse error '%U'", format_unformat_error, i);
21280           return -99;
21281         }
21282     }
21283
21284   vec_add1 (sys_name, 0);
21285
21286   M (LLDP_CONFIG, mp);
21287   mp->tx_hold = htonl (tx_hold);
21288   mp->tx_interval = htonl (tx_interval);
21289   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21290   vec_free (sys_name);
21291
21292   S (mp);
21293   W (ret);
21294   return ret;
21295 }
21296
21297 static int
21298 api_sw_interface_set_lldp (vat_main_t * vam)
21299 {
21300   unformat_input_t *i = vam->input;
21301   vl_api_sw_interface_set_lldp_t *mp;
21302   u32 sw_if_index = ~0;
21303   u32 enable = 1;
21304   u8 *port_desc = NULL, *mgmt_oid = NULL;
21305   ip4_address_t ip4_addr;
21306   ip6_address_t ip6_addr;
21307   int ret;
21308
21309   memset (&ip4_addr, 0, sizeof (ip4_addr));
21310   memset (&ip6_addr, 0, sizeof (ip6_addr));
21311
21312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21313     {
21314       if (unformat (i, "disable"))
21315         enable = 0;
21316       else
21317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21318         ;
21319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21320         ;
21321       else if (unformat (i, "port-desc %s", &port_desc))
21322         ;
21323       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21324         ;
21325       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21326         ;
21327       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21328         ;
21329       else
21330         break;
21331     }
21332
21333   if (sw_if_index == ~0)
21334     {
21335       errmsg ("missing interface name or sw_if_index");
21336       return -99;
21337     }
21338
21339   /* Construct the API message */
21340   vec_add1 (port_desc, 0);
21341   vec_add1 (mgmt_oid, 0);
21342   M (SW_INTERFACE_SET_LLDP, mp);
21343   mp->sw_if_index = ntohl (sw_if_index);
21344   mp->enable = enable;
21345   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21346   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21347   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21348   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21349   vec_free (port_desc);
21350   vec_free (mgmt_oid);
21351
21352   S (mp);
21353   W (ret);
21354   return ret;
21355 }
21356
21357 static int
21358 api_tcp_configure_src_addresses (vat_main_t * vam)
21359 {
21360   vl_api_tcp_configure_src_addresses_t *mp;
21361   unformat_input_t *i = vam->input;
21362   ip4_address_t v4first, v4last;
21363   ip6_address_t v6first, v6last;
21364   u8 range_set = 0;
21365   u32 vrf_id = 0;
21366   int ret;
21367
21368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21369     {
21370       if (unformat (i, "%U - %U",
21371                     unformat_ip4_address, &v4first,
21372                     unformat_ip4_address, &v4last))
21373         {
21374           if (range_set)
21375             {
21376               errmsg ("one range per message (range already set)");
21377               return -99;
21378             }
21379           range_set = 1;
21380         }
21381       else if (unformat (i, "%U - %U",
21382                          unformat_ip6_address, &v6first,
21383                          unformat_ip6_address, &v6last))
21384         {
21385           if (range_set)
21386             {
21387               errmsg ("one range per message (range already set)");
21388               return -99;
21389             }
21390           range_set = 2;
21391         }
21392       else if (unformat (i, "vrf %d", &vrf_id))
21393         ;
21394       else
21395         break;
21396     }
21397
21398   if (range_set == 0)
21399     {
21400       errmsg ("address range not set");
21401       return -99;
21402     }
21403
21404   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21405   mp->vrf_id = ntohl (vrf_id);
21406   /* ipv6? */
21407   if (range_set == 2)
21408     {
21409       mp->is_ipv6 = 1;
21410       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21411       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21412     }
21413   else
21414     {
21415       mp->is_ipv6 = 0;
21416       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21417       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21418     }
21419   S (mp);
21420   W (ret);
21421   return ret;
21422 }
21423
21424 static void vl_api_app_namespace_add_del_reply_t_handler
21425   (vl_api_app_namespace_add_del_reply_t * mp)
21426 {
21427   vat_main_t *vam = &vat_main;
21428   i32 retval = ntohl (mp->retval);
21429   if (vam->async_mode)
21430     {
21431       vam->async_errors += (retval < 0);
21432     }
21433   else
21434     {
21435       vam->retval = retval;
21436       if (retval == 0)
21437         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21438       vam->result_ready = 1;
21439     }
21440 }
21441
21442 static void vl_api_app_namespace_add_del_reply_t_handler_json
21443   (vl_api_app_namespace_add_del_reply_t * mp)
21444 {
21445   vat_main_t *vam = &vat_main;
21446   vat_json_node_t node;
21447
21448   vat_json_init_object (&node);
21449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21450   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21451
21452   vat_json_print (vam->ofp, &node);
21453   vat_json_free (&node);
21454
21455   vam->retval = ntohl (mp->retval);
21456   vam->result_ready = 1;
21457 }
21458
21459 static int
21460 api_app_namespace_add_del (vat_main_t * vam)
21461 {
21462   vl_api_app_namespace_add_del_t *mp;
21463   unformat_input_t *i = vam->input;
21464   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21465   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21466   u64 secret;
21467   int ret;
21468
21469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21470     {
21471       if (unformat (i, "id %_%v%_", &ns_id))
21472         ;
21473       else if (unformat (i, "secret %lu", &secret))
21474         secret_set = 1;
21475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21476         sw_if_index_set = 1;
21477       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21478         ;
21479       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21480         ;
21481       else
21482         break;
21483     }
21484   if (!ns_id || !secret_set || !sw_if_index_set)
21485     {
21486       errmsg ("namespace id, secret and sw_if_index must be set");
21487       return -99;
21488     }
21489   if (vec_len (ns_id) > 64)
21490     {
21491       errmsg ("namespace id too long");
21492       return -99;
21493     }
21494   M (APP_NAMESPACE_ADD_DEL, mp);
21495
21496   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21497   mp->namespace_id_len = vec_len (ns_id);
21498   mp->secret = clib_host_to_net_u64 (secret);
21499   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21500   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21501   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21502   vec_free (ns_id);
21503   S (mp);
21504   W (ret);
21505   return ret;
21506 }
21507
21508 static int
21509 api_memfd_segment_create (vat_main_t * vam)
21510 {
21511 #if VPP_API_TEST_BUILTIN == 0
21512   unformat_input_t *i = vam->input;
21513   vl_api_memfd_segment_create_t *mp;
21514   u64 size = 64 << 20;
21515   int ret;
21516
21517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21518     {
21519       if (unformat (i, "size %U", unformat_memory_size, &size))
21520         ;
21521       else
21522         break;
21523     }
21524
21525   M (MEMFD_SEGMENT_CREATE, mp);
21526   mp->requested_size = size;
21527   S (mp);
21528   W (ret);
21529   return ret;
21530
21531 #else
21532   errmsg ("memfd_segment_create (builtin) not supported");
21533   return -99;
21534 #endif
21535 }
21536
21537 static int
21538 api_dns_enable_disable (vat_main_t * vam)
21539 {
21540   unformat_input_t *line_input = vam->input;
21541   vl_api_dns_enable_disable_t *mp;
21542   u8 enable_disable = 1;
21543   int ret;
21544
21545   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21546     {
21547       if (unformat (line_input, "disable"))
21548         enable_disable = 0;
21549       if (unformat (line_input, "enable"))
21550         enable_disable = 1;
21551       else
21552         break;
21553     }
21554
21555   /* Construct the API message */
21556   M (DNS_ENABLE_DISABLE, mp);
21557   mp->enable = enable_disable;
21558
21559   /* send it... */
21560   S (mp);
21561   /* Wait for the reply */
21562   W (ret);
21563   return ret;
21564 }
21565
21566 static int
21567 api_dns_resolve_name (vat_main_t * vam)
21568 {
21569   unformat_input_t *line_input = vam->input;
21570   vl_api_dns_resolve_name_t *mp;
21571   u8 *name = 0;
21572   int ret;
21573
21574   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21575     {
21576       if (unformat (line_input, "%s", &name))
21577         ;
21578       else
21579         break;
21580     }
21581
21582   if (vec_len (name) > 127)
21583     {
21584       errmsg ("name too long");
21585       return -99;
21586     }
21587
21588   /* Construct the API message */
21589   M (DNS_RESOLVE_NAME, mp);
21590   memcpy (mp->name, name, vec_len (name));
21591   vec_free (name);
21592
21593   /* send it... */
21594   S (mp);
21595   /* Wait for the reply */
21596   W (ret);
21597   return ret;
21598 }
21599
21600 static int
21601 api_dns_resolve_ip (vat_main_t * vam)
21602 {
21603   unformat_input_t *line_input = vam->input;
21604   vl_api_dns_resolve_ip_t *mp;
21605   int is_ip6 = -1;
21606   ip4_address_t addr4;
21607   ip6_address_t addr6;
21608   int ret;
21609
21610   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21611     {
21612       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21613         is_ip6 = 1;
21614       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21615         is_ip6 = 0;
21616       else
21617         break;
21618     }
21619
21620   if (is_ip6 == -1)
21621     {
21622       errmsg ("missing address");
21623       return -99;
21624     }
21625
21626   /* Construct the API message */
21627   M (DNS_RESOLVE_IP, mp);
21628   mp->is_ip6 = is_ip6;
21629   if (is_ip6)
21630     memcpy (mp->address, &addr6, sizeof (addr6));
21631   else
21632     memcpy (mp->address, &addr4, sizeof (addr4));
21633
21634   /* send it... */
21635   S (mp);
21636   /* Wait for the reply */
21637   W (ret);
21638   return ret;
21639 }
21640
21641 static int
21642 api_dns_name_server_add_del (vat_main_t * vam)
21643 {
21644   unformat_input_t *i = vam->input;
21645   vl_api_dns_name_server_add_del_t *mp;
21646   u8 is_add = 1;
21647   ip6_address_t ip6_server;
21648   ip4_address_t ip4_server;
21649   int ip6_set = 0;
21650   int ip4_set = 0;
21651   int ret = 0;
21652
21653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21654     {
21655       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21656         ip6_set = 1;
21657       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21658         ip4_set = 1;
21659       else if (unformat (i, "del"))
21660         is_add = 0;
21661       else
21662         {
21663           clib_warning ("parse error '%U'", format_unformat_error, i);
21664           return -99;
21665         }
21666     }
21667
21668   if (ip4_set && ip6_set)
21669     {
21670       errmsg ("Only one server address allowed per message");
21671       return -99;
21672     }
21673   if ((ip4_set + ip6_set) == 0)
21674     {
21675       errmsg ("Server address required");
21676       return -99;
21677     }
21678
21679   /* Construct the API message */
21680   M (DNS_NAME_SERVER_ADD_DEL, mp);
21681
21682   if (ip6_set)
21683     {
21684       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21685       mp->is_ip6 = 1;
21686     }
21687   else
21688     {
21689       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21690       mp->is_ip6 = 0;
21691     }
21692
21693   mp->is_add = is_add;
21694
21695   /* send it... */
21696   S (mp);
21697
21698   /* Wait for a reply, return good/bad news  */
21699   W (ret);
21700   return ret;
21701 }
21702
21703 static void
21704 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21705 {
21706   vat_main_t *vam = &vat_main;
21707
21708   if (mp->is_ip4)
21709     {
21710       print (vam->ofp,
21711              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21712              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21713              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21714              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21715              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21716              clib_net_to_host_u32 (mp->action_index), mp->tag);
21717     }
21718   else
21719     {
21720       print (vam->ofp,
21721              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21722              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21723              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21724              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21725              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21726              clib_net_to_host_u32 (mp->action_index), mp->tag);
21727     }
21728 }
21729
21730 static void
21731 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21732                                              mp)
21733 {
21734   vat_main_t *vam = &vat_main;
21735   vat_json_node_t *node = NULL;
21736   struct in6_addr ip6;
21737   struct in_addr ip4;
21738
21739   if (VAT_JSON_ARRAY != vam->json_tree.type)
21740     {
21741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21742       vat_json_init_array (&vam->json_tree);
21743     }
21744   node = vat_json_array_add (&vam->json_tree);
21745   vat_json_init_object (node);
21746
21747   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21748   vat_json_object_add_uint (node, "appns_index",
21749                             clib_net_to_host_u32 (mp->appns_index));
21750   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21751   vat_json_object_add_uint (node, "scope", mp->scope);
21752   vat_json_object_add_uint (node, "action_index",
21753                             clib_net_to_host_u32 (mp->action_index));
21754   vat_json_object_add_uint (node, "lcl_port",
21755                             clib_net_to_host_u16 (mp->lcl_port));
21756   vat_json_object_add_uint (node, "rmt_port",
21757                             clib_net_to_host_u16 (mp->rmt_port));
21758   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21759   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21760   vat_json_object_add_string_copy (node, "tag", mp->tag);
21761   if (mp->is_ip4)
21762     {
21763       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21764       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21765       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21766       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21767     }
21768   else
21769     {
21770       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21771       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21772       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21773       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21774     }
21775 }
21776
21777 static int
21778 api_session_rule_add_del (vat_main_t * vam)
21779 {
21780   vl_api_session_rule_add_del_t *mp;
21781   unformat_input_t *i = vam->input;
21782   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21783   u32 appns_index = 0, scope = 0;
21784   ip4_address_t lcl_ip4, rmt_ip4;
21785   ip6_address_t lcl_ip6, rmt_ip6;
21786   u8 is_ip4 = 1, conn_set = 0;
21787   u8 is_add = 1, *tag = 0;
21788   int ret;
21789
21790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21791     {
21792       if (unformat (i, "del"))
21793         is_add = 0;
21794       else if (unformat (i, "add"))
21795         ;
21796       else if (unformat (i, "proto tcp"))
21797         proto = 0;
21798       else if (unformat (i, "proto udp"))
21799         proto = 1;
21800       else if (unformat (i, "appns %d", &appns_index))
21801         ;
21802       else if (unformat (i, "scope %d", &scope))
21803         ;
21804       else if (unformat (i, "tag %_%v%_", &tag))
21805         ;
21806       else
21807         if (unformat
21808             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21809              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21810              &rmt_port))
21811         {
21812           is_ip4 = 1;
21813           conn_set = 1;
21814         }
21815       else
21816         if (unformat
21817             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21818              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21819              &rmt_port))
21820         {
21821           is_ip4 = 0;
21822           conn_set = 1;
21823         }
21824       else if (unformat (i, "action %d", &action))
21825         ;
21826       else
21827         break;
21828     }
21829   if (proto == ~0 || !conn_set || action == ~0)
21830     {
21831       errmsg ("transport proto, connection and action must be set");
21832       return -99;
21833     }
21834
21835   if (scope > 3)
21836     {
21837       errmsg ("scope should be 0-3");
21838       return -99;
21839     }
21840
21841   M (SESSION_RULE_ADD_DEL, mp);
21842
21843   mp->is_ip4 = is_ip4;
21844   mp->transport_proto = proto;
21845   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21846   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21847   mp->lcl_plen = lcl_plen;
21848   mp->rmt_plen = rmt_plen;
21849   mp->action_index = clib_host_to_net_u32 (action);
21850   mp->appns_index = clib_host_to_net_u32 (appns_index);
21851   mp->scope = scope;
21852   mp->is_add = is_add;
21853   if (is_ip4)
21854     {
21855       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21856       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21857     }
21858   else
21859     {
21860       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21861       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21862     }
21863   if (tag)
21864     {
21865       clib_memcpy (mp->tag, tag, vec_len (tag));
21866       vec_free (tag);
21867     }
21868
21869   S (mp);
21870   W (ret);
21871   return ret;
21872 }
21873
21874 static int
21875 api_session_rules_dump (vat_main_t * vam)
21876 {
21877   vl_api_session_rules_dump_t *mp;
21878   vl_api_control_ping_t *mp_ping;
21879   int ret;
21880
21881   if (!vam->json_output)
21882     {
21883       print (vam->ofp, "%=20s", "Session Rules");
21884     }
21885
21886   M (SESSION_RULES_DUMP, mp);
21887   /* send it... */
21888   S (mp);
21889
21890   /* Use a control ping for synchronization */
21891   MPING (CONTROL_PING, mp_ping);
21892   S (mp_ping);
21893
21894   /* Wait for a reply... */
21895   W (ret);
21896   return ret;
21897 }
21898
21899 static int
21900 api_ip_container_proxy_add_del (vat_main_t * vam)
21901 {
21902   vl_api_ip_container_proxy_add_del_t *mp;
21903   unformat_input_t *i = vam->input;
21904   u32 plen = ~0, sw_if_index = ~0;
21905   ip4_address_t ip4;
21906   ip6_address_t ip6;
21907   u8 is_ip4 = 1;
21908   u8 is_add = 1;
21909   int ret;
21910
21911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21912     {
21913       if (unformat (i, "del"))
21914         is_add = 0;
21915       else if (unformat (i, "add"))
21916         ;
21917       if (unformat (i, "%U", unformat_ip4_address, &ip4))
21918         {
21919           is_ip4 = 1;
21920           plen = 32;
21921         }
21922       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
21923         {
21924           is_ip4 = 0;
21925           plen = 128;
21926         }
21927       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21928         ;
21929       else
21930         break;
21931     }
21932   if (sw_if_index == ~0 || plen == ~0)
21933     {
21934       errmsg ("address and sw_if_index must be set");
21935       return -99;
21936     }
21937
21938   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21939
21940   mp->is_ip4 = is_ip4;
21941   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21942   mp->plen = plen;
21943   mp->is_add = is_add;
21944   if (is_ip4)
21945     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
21946   else
21947     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
21948
21949   S (mp);
21950   W (ret);
21951   return ret;
21952 }
21953
21954 static int
21955 q_or_quit (vat_main_t * vam)
21956 {
21957 #if VPP_API_TEST_BUILTIN == 0
21958   longjmp (vam->jump_buf, 1);
21959 #endif
21960   return 0;                     /* not so much */
21961 }
21962
21963 static int
21964 q (vat_main_t * vam)
21965 {
21966   return q_or_quit (vam);
21967 }
21968
21969 static int
21970 quit (vat_main_t * vam)
21971 {
21972   return q_or_quit (vam);
21973 }
21974
21975 static int
21976 comment (vat_main_t * vam)
21977 {
21978   return 0;
21979 }
21980
21981 static int
21982 cmd_cmp (void *a1, void *a2)
21983 {
21984   u8 **c1 = a1;
21985   u8 **c2 = a2;
21986
21987   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21988 }
21989
21990 static int
21991 help (vat_main_t * vam)
21992 {
21993   u8 **cmds = 0;
21994   u8 *name = 0;
21995   hash_pair_t *p;
21996   unformat_input_t *i = vam->input;
21997   int j;
21998
21999   if (unformat (i, "%s", &name))
22000     {
22001       uword *hs;
22002
22003       vec_add1 (name, 0);
22004
22005       hs = hash_get_mem (vam->help_by_name, name);
22006       if (hs)
22007         print (vam->ofp, "usage: %s %s", name, hs[0]);
22008       else
22009         print (vam->ofp, "No such msg / command '%s'", name);
22010       vec_free (name);
22011       return 0;
22012     }
22013
22014   print (vam->ofp, "Help is available for the following:");
22015
22016     /* *INDENT-OFF* */
22017     hash_foreach_pair (p, vam->function_by_name,
22018     ({
22019       vec_add1 (cmds, (u8 *)(p->key));
22020     }));
22021     /* *INDENT-ON* */
22022
22023   vec_sort_with_function (cmds, cmd_cmp);
22024
22025   for (j = 0; j < vec_len (cmds); j++)
22026     print (vam->ofp, "%s", cmds[j]);
22027
22028   vec_free (cmds);
22029   return 0;
22030 }
22031
22032 static int
22033 set (vat_main_t * vam)
22034 {
22035   u8 *name = 0, *value = 0;
22036   unformat_input_t *i = vam->input;
22037
22038   if (unformat (i, "%s", &name))
22039     {
22040       /* The input buffer is a vector, not a string. */
22041       value = vec_dup (i->buffer);
22042       vec_delete (value, i->index, 0);
22043       /* Almost certainly has a trailing newline */
22044       if (value[vec_len (value) - 1] == '\n')
22045         value[vec_len (value) - 1] = 0;
22046       /* Make sure it's a proper string, one way or the other */
22047       vec_add1 (value, 0);
22048       (void) clib_macro_set_value (&vam->macro_main,
22049                                    (char *) name, (char *) value);
22050     }
22051   else
22052     errmsg ("usage: set <name> <value>");
22053
22054   vec_free (name);
22055   vec_free (value);
22056   return 0;
22057 }
22058
22059 static int
22060 unset (vat_main_t * vam)
22061 {
22062   u8 *name = 0;
22063
22064   if (unformat (vam->input, "%s", &name))
22065     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22066       errmsg ("unset: %s wasn't set", name);
22067   vec_free (name);
22068   return 0;
22069 }
22070
22071 typedef struct
22072 {
22073   u8 *name;
22074   u8 *value;
22075 } macro_sort_t;
22076
22077
22078 static int
22079 macro_sort_cmp (void *a1, void *a2)
22080 {
22081   macro_sort_t *s1 = a1;
22082   macro_sort_t *s2 = a2;
22083
22084   return strcmp ((char *) (s1->name), (char *) (s2->name));
22085 }
22086
22087 static int
22088 dump_macro_table (vat_main_t * vam)
22089 {
22090   macro_sort_t *sort_me = 0, *sm;
22091   int i;
22092   hash_pair_t *p;
22093
22094     /* *INDENT-OFF* */
22095     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22096     ({
22097       vec_add2 (sort_me, sm, 1);
22098       sm->name = (u8 *)(p->key);
22099       sm->value = (u8 *) (p->value[0]);
22100     }));
22101     /* *INDENT-ON* */
22102
22103   vec_sort_with_function (sort_me, macro_sort_cmp);
22104
22105   if (vec_len (sort_me))
22106     print (vam->ofp, "%-15s%s", "Name", "Value");
22107   else
22108     print (vam->ofp, "The macro table is empty...");
22109
22110   for (i = 0; i < vec_len (sort_me); i++)
22111     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22112   return 0;
22113 }
22114
22115 static int
22116 dump_node_table (vat_main_t * vam)
22117 {
22118   int i, j;
22119   vlib_node_t *node, *next_node;
22120
22121   if (vec_len (vam->graph_nodes) == 0)
22122     {
22123       print (vam->ofp, "Node table empty, issue get_node_graph...");
22124       return 0;
22125     }
22126
22127   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22128     {
22129       node = vam->graph_nodes[i];
22130       print (vam->ofp, "[%d] %s", i, node->name);
22131       for (j = 0; j < vec_len (node->next_nodes); j++)
22132         {
22133           if (node->next_nodes[j] != ~0)
22134             {
22135               next_node = vam->graph_nodes[node->next_nodes[j]];
22136               print (vam->ofp, "  [%d] %s", j, next_node->name);
22137             }
22138         }
22139     }
22140   return 0;
22141 }
22142
22143 static int
22144 value_sort_cmp (void *a1, void *a2)
22145 {
22146   name_sort_t *n1 = a1;
22147   name_sort_t *n2 = a2;
22148
22149   if (n1->value < n2->value)
22150     return -1;
22151   if (n1->value > n2->value)
22152     return 1;
22153   return 0;
22154 }
22155
22156
22157 static int
22158 dump_msg_api_table (vat_main_t * vam)
22159 {
22160   api_main_t *am = &api_main;
22161   name_sort_t *nses = 0, *ns;
22162   hash_pair_t *hp;
22163   int i;
22164
22165   /* *INDENT-OFF* */
22166   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22167   ({
22168     vec_add2 (nses, ns, 1);
22169     ns->name = (u8 *)(hp->key);
22170     ns->value = (u32) hp->value[0];
22171   }));
22172   /* *INDENT-ON* */
22173
22174   vec_sort_with_function (nses, value_sort_cmp);
22175
22176   for (i = 0; i < vec_len (nses); i++)
22177     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22178   vec_free (nses);
22179   return 0;
22180 }
22181
22182 static int
22183 get_msg_id (vat_main_t * vam)
22184 {
22185   u8 *name_and_crc;
22186   u32 message_index;
22187
22188   if (unformat (vam->input, "%s", &name_and_crc))
22189     {
22190       message_index = vl_api_get_msg_index (name_and_crc);
22191       if (message_index == ~0)
22192         {
22193           print (vam->ofp, " '%s' not found", name_and_crc);
22194           return 0;
22195         }
22196       print (vam->ofp, " '%s' has message index %d",
22197              name_and_crc, message_index);
22198       return 0;
22199     }
22200   errmsg ("name_and_crc required...");
22201   return 0;
22202 }
22203
22204 static int
22205 search_node_table (vat_main_t * vam)
22206 {
22207   unformat_input_t *line_input = vam->input;
22208   u8 *node_to_find;
22209   int j;
22210   vlib_node_t *node, *next_node;
22211   uword *p;
22212
22213   if (vam->graph_node_index_by_name == 0)
22214     {
22215       print (vam->ofp, "Node table empty, issue get_node_graph...");
22216       return 0;
22217     }
22218
22219   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22220     {
22221       if (unformat (line_input, "%s", &node_to_find))
22222         {
22223           vec_add1 (node_to_find, 0);
22224           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22225           if (p == 0)
22226             {
22227               print (vam->ofp, "%s not found...", node_to_find);
22228               goto out;
22229             }
22230           node = vam->graph_nodes[p[0]];
22231           print (vam->ofp, "[%d] %s", p[0], node->name);
22232           for (j = 0; j < vec_len (node->next_nodes); j++)
22233             {
22234               if (node->next_nodes[j] != ~0)
22235                 {
22236                   next_node = vam->graph_nodes[node->next_nodes[j]];
22237                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22238                 }
22239             }
22240         }
22241
22242       else
22243         {
22244           clib_warning ("parse error '%U'", format_unformat_error,
22245                         line_input);
22246           return -99;
22247         }
22248
22249     out:
22250       vec_free (node_to_find);
22251
22252     }
22253
22254   return 0;
22255 }
22256
22257
22258 static int
22259 script (vat_main_t * vam)
22260 {
22261 #if (VPP_API_TEST_BUILTIN==0)
22262   u8 *s = 0;
22263   char *save_current_file;
22264   unformat_input_t save_input;
22265   jmp_buf save_jump_buf;
22266   u32 save_line_number;
22267
22268   FILE *new_fp, *save_ifp;
22269
22270   if (unformat (vam->input, "%s", &s))
22271     {
22272       new_fp = fopen ((char *) s, "r");
22273       if (new_fp == 0)
22274         {
22275           errmsg ("Couldn't open script file %s", s);
22276           vec_free (s);
22277           return -99;
22278         }
22279     }
22280   else
22281     {
22282       errmsg ("Missing script name");
22283       return -99;
22284     }
22285
22286   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22287   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22288   save_ifp = vam->ifp;
22289   save_line_number = vam->input_line_number;
22290   save_current_file = (char *) vam->current_file;
22291
22292   vam->input_line_number = 0;
22293   vam->ifp = new_fp;
22294   vam->current_file = s;
22295   do_one_file (vam);
22296
22297   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22298   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22299   vam->ifp = save_ifp;
22300   vam->input_line_number = save_line_number;
22301   vam->current_file = (u8 *) save_current_file;
22302   vec_free (s);
22303
22304   return 0;
22305 #else
22306   clib_warning ("use the exec command...");
22307   return -99;
22308 #endif
22309 }
22310
22311 static int
22312 echo (vat_main_t * vam)
22313 {
22314   print (vam->ofp, "%v", vam->input->buffer);
22315   return 0;
22316 }
22317
22318 /* List of API message constructors, CLI names map to api_xxx */
22319 #define foreach_vpe_api_msg                                             \
22320 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22321 _(sw_interface_dump,"")                                                 \
22322 _(sw_interface_set_flags,                                               \
22323   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22324 _(sw_interface_add_del_address,                                         \
22325   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22326 _(sw_interface_set_rx_mode,                                             \
22327   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22328 _(sw_interface_set_table,                                               \
22329   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22330 _(sw_interface_set_mpls_enable,                                         \
22331   "<intfc> | sw_if_index [disable | dis]")                              \
22332 _(sw_interface_set_vpath,                                               \
22333   "<intfc> | sw_if_index <id> enable | disable")                        \
22334 _(sw_interface_set_vxlan_bypass,                                        \
22335   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22336 _(sw_interface_set_geneve_bypass,                                       \
22337   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22338 _(sw_interface_set_l2_xconnect,                                         \
22339   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22340   "enable | disable")                                                   \
22341 _(sw_interface_set_l2_bridge,                                           \
22342   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22343   "[shg <split-horizon-group>] [bvi]\n"                                 \
22344   "enable | disable")                                                   \
22345 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22346 _(bridge_domain_add_del,                                                \
22347   "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") \
22348 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22349 _(l2fib_add_del,                                                        \
22350   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22351 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22352 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22353 _(l2_flags,                                                             \
22354   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22355 _(bridge_flags,                                                         \
22356   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22357 _(tap_connect,                                                          \
22358   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22359 _(tap_modify,                                                           \
22360   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22361 _(tap_delete,                                                           \
22362   "<vpp-if-name> | sw_if_index <id>")                                   \
22363 _(sw_interface_tap_dump, "")                                            \
22364 _(ip_table_add_del,                                                     \
22365   "table-id <n> [ipv6]\n")                                              \
22366 _(ip_add_del_route,                                                     \
22367   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22368   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22369   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22370   "[multipath] [count <n>]")                                            \
22371 _(ip_mroute_add_del,                                                    \
22372   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22373   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22374 _(mpls_table_add_del,                                                   \
22375   "table-id <n>\n")                                                     \
22376 _(mpls_route_add_del,                                                   \
22377   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22378   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22379   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22380   "[multipath] [count <n>]")                                            \
22381 _(mpls_ip_bind_unbind,                                                  \
22382   "<label> <addr/len>")                                                 \
22383 _(mpls_tunnel_add_del,                                                  \
22384   " via <addr> [table-id <n>]\n"                                        \
22385   "sw_if_index <id>] [l2]  [del]")                                      \
22386 _(bier_table_add_del,                                                   \
22387   "<label> <sub-domain> <set> <bsl> [del]")                             \
22388 _(bier_route_add_del,                                                   \
22389   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22390   "[<intfc> | sw_if_index <id>]"                                        \
22391   "[weight <n>] [del] [multipath]")                                     \
22392 _(proxy_arp_add_del,                                                    \
22393   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22394 _(proxy_arp_intfc_enable_disable,                                       \
22395   "<intfc> | sw_if_index <id> enable | disable")                        \
22396 _(sw_interface_set_unnumbered,                                          \
22397   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22398 _(ip_neighbor_add_del,                                                  \
22399   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22400   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22401 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22402 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22403   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22404   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22405   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22406 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22407 _(reset_fib, "vrf <n> [ipv6]")                                          \
22408 _(dhcp_proxy_config,                                                    \
22409   "svr <v46-address> src <v46-address>\n"                               \
22410    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22411 _(dhcp_proxy_set_vss,                                                   \
22412   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22413 _(dhcp_proxy_dump, "ip6")                                               \
22414 _(dhcp_client_config,                                                   \
22415   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22416 _(set_ip_flow_hash,                                                     \
22417   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22418 _(sw_interface_ip6_enable_disable,                                      \
22419   "<intfc> | sw_if_index <id> enable | disable")                        \
22420 _(sw_interface_ip6_set_link_local_address,                              \
22421   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22422 _(ip6nd_proxy_add_del,                                                  \
22423   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22424 _(ip6nd_proxy_dump, "")                                                 \
22425 _(sw_interface_ip6nd_ra_prefix,                                         \
22426   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22427   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22428   "[nolink] [isno]")                                                    \
22429 _(sw_interface_ip6nd_ra_config,                                         \
22430   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22431   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22432   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22433 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22434 _(l2_patch_add_del,                                                     \
22435   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22436   "enable | disable")                                                   \
22437 _(sr_localsid_add_del,                                                  \
22438   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22439   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22440 _(classify_add_del_table,                                               \
22441   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22442   " [del] [del-chain] mask <mask-value>\n"                              \
22443   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22444   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22445 _(classify_add_del_session,                                             \
22446   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22447   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22448   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22449   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22450 _(classify_set_interface_ip_table,                                      \
22451   "<intfc> | sw_if_index <nn> table <nn>")                              \
22452 _(classify_set_interface_l2_tables,                                     \
22453   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22454   "  [other-table <nn>]")                                               \
22455 _(get_node_index, "node <node-name")                                    \
22456 _(add_node_next, "node <node-name> next <next-node-name>")              \
22457 _(l2tpv3_create_tunnel,                                                 \
22458   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22459   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22460   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22461 _(l2tpv3_set_tunnel_cookies,                                            \
22462   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22463   "[new_remote_cookie <nn>]\n")                                         \
22464 _(l2tpv3_interface_enable_disable,                                      \
22465   "<intfc> | sw_if_index <nn> enable | disable")                        \
22466 _(l2tpv3_set_lookup_key,                                                \
22467   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22468 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22469 _(vxlan_add_del_tunnel,                                                 \
22470   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22471   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22472   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22473 _(geneve_add_del_tunnel,                                                \
22474   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22475   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22476   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22477 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22478 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22479 _(gre_add_del_tunnel,                                                   \
22480   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22481 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22482 _(l2_fib_clear_table, "")                                               \
22483 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22484 _(l2_interface_vlan_tag_rewrite,                                        \
22485   "<intfc> | sw_if_index <nn> \n"                                       \
22486   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22487   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22488 _(create_vhost_user_if,                                                 \
22489         "socket <filename> [server] [renumber <dev_instance>] "         \
22490         "[mac <mac_address>]")                                          \
22491 _(modify_vhost_user_if,                                                 \
22492         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22493         "[server] [renumber <dev_instance>]")                           \
22494 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22495 _(sw_interface_vhost_user_dump, "")                                     \
22496 _(show_version, "")                                                     \
22497 _(vxlan_gpe_add_del_tunnel,                                             \
22498   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22499   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22500   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22501   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22502 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22503 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22504 _(interface_name_renumber,                                              \
22505   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22506 _(input_acl_set_interface,                                              \
22507   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22508   "  [l2-table <nn>] [del]")                                            \
22509 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22510 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22511 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22512 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22513 _(ip_dump, "ipv4 | ipv6")                                               \
22514 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22515 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22516   "  spid_id <n> ")                                                     \
22517 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22518   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22519   "  integ_alg <alg> integ_key <hex>")                                  \
22520 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22521   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22522   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22523   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22524 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22525 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22526   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22527   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22528   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22529 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22530 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22531   "  <alg> <hex>\n")                                                    \
22532 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22533 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22534 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22535   "(auth_data 0x<data> | auth_data <data>)")                            \
22536 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22537   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22538 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22539   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22540   "(local|remote)")                                                     \
22541 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22542 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22543 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22544 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22545 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22546 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22547 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22548 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22549 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22550 _(delete_loopback,"sw_if_index <nn>")                                   \
22551 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22552 _(map_add_domain,                                                       \
22553   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22554   "ip6-src <ip6addr> "                                                  \
22555   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22556 _(map_del_domain, "index <n>")                                          \
22557 _(map_add_del_rule,                                                     \
22558   "index <n> psid <n> dst <ip6addr> [del]")                             \
22559 _(map_domain_dump, "")                                                  \
22560 _(map_rule_dump, "index <map-domain>")                                  \
22561 _(want_interface_events,  "enable|disable")                             \
22562 _(want_stats,"enable|disable")                                          \
22563 _(get_first_msg_id, "client <name>")                                    \
22564 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22565 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22566   "fib-id <nn> [ip4][ip6][default]")                                    \
22567 _(get_node_graph, " ")                                                  \
22568 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22569 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22570 _(ioam_disable, "")                                                     \
22571 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22572                             " sw_if_index <sw_if_index> p <priority> "  \
22573                             "w <weight>] [del]")                        \
22574 _(one_add_del_locator, "locator-set <locator_name> "                    \
22575                         "iface <intf> | sw_if_index <sw_if_index> "     \
22576                         "p <priority> w <weight> [del]")                \
22577 _(one_add_del_local_eid,"vni <vni> eid "                                \
22578                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22579                          "locator-set <locator_name> [del]"             \
22580                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22581 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22582 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22583 _(one_enable_disable, "enable|disable")                                 \
22584 _(one_map_register_enable_disable, "enable|disable")                    \
22585 _(one_map_register_fallback_threshold, "<value>")                       \
22586 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22587 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22588                                "[seid <seid>] "                         \
22589                                "rloc <locator> p <prio> "               \
22590                                "w <weight> [rloc <loc> ... ] "          \
22591                                "action <action> [del-all]")             \
22592 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22593                           "<local-eid>")                                \
22594 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22595 _(one_use_petr, "ip-address> | disable")                                \
22596 _(one_map_request_mode, "src-dst|dst-only")                             \
22597 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22598 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22599 _(one_locator_set_dump, "[local | remote]")                             \
22600 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22601 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22602                        "[local] | [remote]")                            \
22603 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22604 _(one_ndp_bd_get, "")                                                   \
22605 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22606 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22607 _(one_l2_arp_bd_get, "")                                                \
22608 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22609 _(one_stats_enable_disable, "enable|disalbe")                           \
22610 _(show_one_stats_enable_disable, "")                                    \
22611 _(one_eid_table_vni_dump, "")                                           \
22612 _(one_eid_table_map_dump, "l2|l3")                                      \
22613 _(one_map_resolver_dump, "")                                            \
22614 _(one_map_server_dump, "")                                              \
22615 _(one_adjacencies_get, "vni <vni>")                                     \
22616 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22617 _(show_one_rloc_probe_state, "")                                        \
22618 _(show_one_map_register_state, "")                                      \
22619 _(show_one_status, "")                                                  \
22620 _(one_stats_dump, "")                                                   \
22621 _(one_stats_flush, "")                                                  \
22622 _(one_get_map_request_itr_rlocs, "")                                    \
22623 _(one_map_register_set_ttl, "<ttl>")                                    \
22624 _(one_set_transport_protocol, "udp|api")                                \
22625 _(one_get_transport_protocol, "")                                       \
22626 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22627 _(one_show_xtr_mode, "")                                                \
22628 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22629 _(one_show_pitr_mode, "")                                               \
22630 _(one_enable_disable_petr_mode, "enable|disable")                       \
22631 _(one_show_petr_mode, "")                                               \
22632 _(show_one_nsh_mapping, "")                                             \
22633 _(show_one_pitr, "")                                                    \
22634 _(show_one_use_petr, "")                                                \
22635 _(show_one_map_request_mode, "")                                        \
22636 _(show_one_map_register_ttl, "")                                        \
22637 _(show_one_map_register_fallback_threshold, "")                         \
22638 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22639                             " sw_if_index <sw_if_index> p <priority> "  \
22640                             "w <weight>] [del]")                        \
22641 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22642                         "iface <intf> | sw_if_index <sw_if_index> "     \
22643                         "p <priority> w <weight> [del]")                \
22644 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22645                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22646                          "locator-set <locator_name> [del]"             \
22647                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22648 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22649 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22650 _(lisp_enable_disable, "enable|disable")                                \
22651 _(lisp_map_register_enable_disable, "enable|disable")                   \
22652 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22653 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22654                                "[seid <seid>] "                         \
22655                                "rloc <locator> p <prio> "               \
22656                                "w <weight> [rloc <loc> ... ] "          \
22657                                "action <action> [del-all]")             \
22658 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22659                           "<local-eid>")                                \
22660 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22661 _(lisp_use_petr, "<ip-address> | disable")                              \
22662 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22663 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22664 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22665 _(lisp_locator_set_dump, "[local | remote]")                            \
22666 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22667 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22668                        "[local] | [remote]")                            \
22669 _(lisp_eid_table_vni_dump, "")                                          \
22670 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22671 _(lisp_map_resolver_dump, "")                                           \
22672 _(lisp_map_server_dump, "")                                             \
22673 _(lisp_adjacencies_get, "vni <vni>")                                    \
22674 _(gpe_fwd_entry_vnis_get, "")                                           \
22675 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22676 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22677                                 "[table <table-id>]")                   \
22678 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22679 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22680 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22681 _(gpe_get_encap_mode, "")                                               \
22682 _(lisp_gpe_add_del_iface, "up|down")                                    \
22683 _(lisp_gpe_enable_disable, "enable|disable")                            \
22684 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22685   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22686 _(show_lisp_rloc_probe_state, "")                                       \
22687 _(show_lisp_map_register_state, "")                                     \
22688 _(show_lisp_status, "")                                                 \
22689 _(lisp_get_map_request_itr_rlocs, "")                                   \
22690 _(show_lisp_pitr, "")                                                   \
22691 _(show_lisp_use_petr, "")                                               \
22692 _(show_lisp_map_request_mode, "")                                       \
22693 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22694 _(af_packet_delete, "name <host interface name>")                       \
22695 _(policer_add_del, "name <policer name> <params> [del]")                \
22696 _(policer_dump, "[name <policer name>]")                                \
22697 _(policer_classify_set_interface,                                       \
22698   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22699   "  [l2-table <nn>] [del]")                                            \
22700 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22701 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22702     "[master|slave]")                                                   \
22703 _(netmap_delete, "name <interface name>")                               \
22704 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22705 _(mpls_fib_dump, "")                                                    \
22706 _(classify_table_ids, "")                                               \
22707 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22708 _(classify_table_info, "table_id <nn>")                                 \
22709 _(classify_session_dump, "table_id <nn>")                               \
22710 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22711     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22712     "[template_interval <nn>] [udp_checksum]")                          \
22713 _(ipfix_exporter_dump, "")                                              \
22714 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22715 _(ipfix_classify_stream_dump, "")                                       \
22716 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22717 _(ipfix_classify_table_dump, "")                                        \
22718 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22719 _(sw_interface_span_dump, "[l2]")                                           \
22720 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22721 _(pg_create_interface, "if_id <nn>")                                    \
22722 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22723 _(pg_enable_disable, "[stream <id>] disable")                           \
22724 _(ip_source_and_port_range_check_add_del,                               \
22725   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22726 _(ip_source_and_port_range_check_interface_add_del,                     \
22727   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22728   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22729 _(ipsec_gre_add_del_tunnel,                                             \
22730   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22731 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22732 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22733 _(l2_interface_pbb_tag_rewrite,                                         \
22734   "<intfc> | sw_if_index <nn> \n"                                       \
22735   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22736   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22737 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22738 _(flow_classify_set_interface,                                          \
22739   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22740 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22741 _(ip_fib_dump, "")                                                      \
22742 _(ip_mfib_dump, "")                                                     \
22743 _(ip6_fib_dump, "")                                                     \
22744 _(ip6_mfib_dump, "")                                                    \
22745 _(feature_enable_disable, "arc_name <arc_name> "                        \
22746   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22747 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22748 "[disable]")                                                            \
22749 _(l2_xconnect_dump, "")                                                 \
22750 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22751 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22752 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22753 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22754 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22755 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22756 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22757   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22758 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22759 _(memfd_segment_create,"size <nnn>")                                    \
22760 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22761 _(dns_enable_disable, "[enable][disable]")                              \
22762 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22763 _(dns_resolve_name, "<hostname>")                                       \
22764 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22765 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22766 _(dns_resolve_name, "<hostname>")                                       \
22767 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22768   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22769 _(session_rules_dump, "")                                               \
22770 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22771
22772 /* List of command functions, CLI names map directly to functions */
22773 #define foreach_cli_function                                    \
22774 _(comment, "usage: comment <ignore-rest-of-line>")              \
22775 _(dump_interface_table, "usage: dump_interface_table")          \
22776 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22777 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22778 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22779 _(dump_stats_table, "usage: dump_stats_table")                  \
22780 _(dump_macro_table, "usage: dump_macro_table ")                 \
22781 _(dump_node_table, "usage: dump_node_table")                    \
22782 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22783 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22784 _(echo, "usage: echo <message>")                                \
22785 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22786 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22787 _(help, "usage: help")                                          \
22788 _(q, "usage: quit")                                             \
22789 _(quit, "usage: quit")                                          \
22790 _(search_node_table, "usage: search_node_table <name>...")      \
22791 _(set, "usage: set <variable-name> <value>")                    \
22792 _(script, "usage: script <file-name>")                          \
22793 _(unset, "usage: unset <variable-name>")
22794 #define _(N,n)                                  \
22795     static void vl_api_##n##_t_handler_uni      \
22796     (vl_api_##n##_t * mp)                       \
22797     {                                           \
22798         vat_main_t * vam = &vat_main;           \
22799         if (vam->json_output) {                 \
22800             vl_api_##n##_t_handler_json(mp);    \
22801         } else {                                \
22802             vl_api_##n##_t_handler(mp);         \
22803         }                                       \
22804     }
22805 foreach_vpe_api_reply_msg;
22806 #if VPP_API_TEST_BUILTIN == 0
22807 foreach_standalone_reply_msg;
22808 #endif
22809 #undef _
22810
22811 void
22812 vat_api_hookup (vat_main_t * vam)
22813 {
22814 #define _(N,n)                                                  \
22815     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22816                            vl_api_##n##_t_handler_uni,          \
22817                            vl_noop_handler,                     \
22818                            vl_api_##n##_t_endian,               \
22819                            vl_api_##n##_t_print,                \
22820                            sizeof(vl_api_##n##_t), 1);
22821   foreach_vpe_api_reply_msg;
22822 #if VPP_API_TEST_BUILTIN == 0
22823   foreach_standalone_reply_msg;
22824 #endif
22825 #undef _
22826
22827 #if (VPP_API_TEST_BUILTIN==0)
22828   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22829
22830   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22831
22832   vam->function_by_name = hash_create_string (0, sizeof (uword));
22833
22834   vam->help_by_name = hash_create_string (0, sizeof (uword));
22835 #endif
22836
22837   /* API messages we can send */
22838 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22839   foreach_vpe_api_msg;
22840 #undef _
22841
22842   /* Help strings */
22843 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22844   foreach_vpe_api_msg;
22845 #undef _
22846
22847   /* CLI functions */
22848 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22849   foreach_cli_function;
22850 #undef _
22851
22852   /* Help strings */
22853 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22854   foreach_cli_function;
22855 #undef _
22856 }
22857
22858 #if VPP_API_TEST_BUILTIN
22859 static clib_error_t *
22860 vat_api_hookup_shim (vlib_main_t * vm)
22861 {
22862   vat_api_hookup (&vat_main);
22863   return 0;
22864 }
22865
22866 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22867 #endif
22868
22869 /*
22870  * fd.io coding-style-patch-verification: ON
22871  *
22872  * Local Variables:
22873  * eval: (c-set-style "gnu")
22874  * End:
22875  */