BIER
[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 _(reset_vrf_reply)                                      \
5190 _(oam_add_del_reply)                                    \
5191 _(reset_fib_reply)                                      \
5192 _(dhcp_proxy_config_reply)                              \
5193 _(dhcp_proxy_set_vss_reply)                             \
5194 _(dhcp_client_config_reply)                             \
5195 _(set_ip_flow_hash_reply)                               \
5196 _(sw_interface_ip6_enable_disable_reply)                \
5197 _(sw_interface_ip6_set_link_local_address_reply)        \
5198 _(ip6nd_proxy_add_del_reply)                            \
5199 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5200 _(sw_interface_ip6nd_ra_config_reply)                   \
5201 _(set_arp_neighbor_limit_reply)                         \
5202 _(l2_patch_add_del_reply)                               \
5203 _(sr_policy_add_reply)                                  \
5204 _(sr_policy_mod_reply)                                  \
5205 _(sr_policy_del_reply)                                  \
5206 _(sr_localsid_add_del_reply)                            \
5207 _(sr_steering_add_del_reply)                            \
5208 _(classify_add_del_session_reply)                       \
5209 _(classify_set_interface_ip_table_reply)                \
5210 _(classify_set_interface_l2_tables_reply)               \
5211 _(l2tpv3_set_tunnel_cookies_reply)                      \
5212 _(l2tpv3_interface_enable_disable_reply)                \
5213 _(l2tpv3_set_lookup_key_reply)                          \
5214 _(l2_fib_clear_table_reply)                             \
5215 _(l2_interface_efp_filter_reply)                        \
5216 _(l2_interface_vlan_tag_rewrite_reply)                  \
5217 _(modify_vhost_user_if_reply)                           \
5218 _(delete_vhost_user_if_reply)                           \
5219 _(want_ip4_arp_events_reply)                            \
5220 _(want_ip6_nd_events_reply)                             \
5221 _(want_l2_macs_events_reply)                            \
5222 _(input_acl_set_interface_reply)                        \
5223 _(ipsec_spd_add_del_reply)                              \
5224 _(ipsec_interface_add_del_spd_reply)                    \
5225 _(ipsec_spd_add_del_entry_reply)                        \
5226 _(ipsec_sad_add_del_entry_reply)                        \
5227 _(ipsec_sa_set_key_reply)                               \
5228 _(ipsec_tunnel_if_add_del_reply)                        \
5229 _(ipsec_tunnel_if_set_key_reply)                        \
5230 _(ipsec_tunnel_if_set_sa_reply)                         \
5231 _(ikev2_profile_add_del_reply)                          \
5232 _(ikev2_profile_set_auth_reply)                         \
5233 _(ikev2_profile_set_id_reply)                           \
5234 _(ikev2_profile_set_ts_reply)                           \
5235 _(ikev2_set_local_key_reply)                            \
5236 _(ikev2_set_responder_reply)                            \
5237 _(ikev2_set_ike_transforms_reply)                       \
5238 _(ikev2_set_esp_transforms_reply)                       \
5239 _(ikev2_set_sa_lifetime_reply)                          \
5240 _(ikev2_initiate_sa_init_reply)                         \
5241 _(ikev2_initiate_del_ike_sa_reply)                      \
5242 _(ikev2_initiate_del_child_sa_reply)                    \
5243 _(ikev2_initiate_rekey_child_sa_reply)                  \
5244 _(delete_loopback_reply)                                \
5245 _(bd_ip_mac_add_del_reply)                              \
5246 _(map_del_domain_reply)                                 \
5247 _(map_add_del_rule_reply)                               \
5248 _(want_interface_events_reply)                          \
5249 _(want_stats_reply)                                     \
5250 _(cop_interface_enable_disable_reply)                   \
5251 _(cop_whitelist_enable_disable_reply)                   \
5252 _(sw_interface_clear_stats_reply)                       \
5253 _(ioam_enable_reply)                                    \
5254 _(ioam_disable_reply)                                   \
5255 _(one_add_del_locator_reply)                            \
5256 _(one_add_del_local_eid_reply)                          \
5257 _(one_add_del_remote_mapping_reply)                     \
5258 _(one_add_del_adjacency_reply)                          \
5259 _(one_add_del_map_resolver_reply)                       \
5260 _(one_add_del_map_server_reply)                         \
5261 _(one_enable_disable_reply)                             \
5262 _(one_rloc_probe_enable_disable_reply)                  \
5263 _(one_map_register_enable_disable_reply)                \
5264 _(one_map_register_set_ttl_reply)                       \
5265 _(one_set_transport_protocol_reply)                     \
5266 _(one_map_register_fallback_threshold_reply)            \
5267 _(one_pitr_set_locator_set_reply)                       \
5268 _(one_map_request_mode_reply)                           \
5269 _(one_add_del_map_request_itr_rlocs_reply)              \
5270 _(one_eid_table_add_del_map_reply)                      \
5271 _(one_use_petr_reply)                                   \
5272 _(one_stats_enable_disable_reply)                       \
5273 _(one_add_del_l2_arp_entry_reply)                       \
5274 _(one_add_del_ndp_entry_reply)                          \
5275 _(one_stats_flush_reply)                                \
5276 _(one_enable_disable_xtr_mode_reply)                    \
5277 _(one_enable_disable_pitr_mode_reply)                   \
5278 _(one_enable_disable_petr_mode_reply)                   \
5279 _(gpe_enable_disable_reply)                             \
5280 _(gpe_set_encap_mode_reply)                             \
5281 _(gpe_add_del_iface_reply)                              \
5282 _(gpe_add_del_native_fwd_rpath_reply)                   \
5283 _(af_packet_delete_reply)                               \
5284 _(policer_classify_set_interface_reply)                 \
5285 _(netmap_create_reply)                                  \
5286 _(netmap_delete_reply)                                  \
5287 _(set_ipfix_exporter_reply)                             \
5288 _(set_ipfix_classify_stream_reply)                      \
5289 _(ipfix_classify_table_add_del_reply)                   \
5290 _(flow_classify_set_interface_reply)                    \
5291 _(sw_interface_span_enable_disable_reply)               \
5292 _(pg_capture_reply)                                     \
5293 _(pg_enable_disable_reply)                              \
5294 _(ip_source_and_port_range_check_add_del_reply)         \
5295 _(ip_source_and_port_range_check_interface_add_del_reply)\
5296 _(delete_subif_reply)                                   \
5297 _(l2_interface_pbb_tag_rewrite_reply)                   \
5298 _(punt_reply)                                           \
5299 _(feature_enable_disable_reply)                         \
5300 _(sw_interface_tag_add_del_reply)                       \
5301 _(sw_interface_set_mtu_reply)                           \
5302 _(p2p_ethernet_add_reply)                               \
5303 _(p2p_ethernet_del_reply)                               \
5304 _(lldp_config_reply)                                    \
5305 _(sw_interface_set_lldp_reply)                          \
5306 _(tcp_configure_src_addresses_reply)                    \
5307 _(app_namespace_add_del_reply)                          \
5308 _(dns_enable_disable_reply)                             \
5309 _(dns_name_server_add_del_reply)                        \
5310 _(session_rule_add_del_reply)                           \
5311 _(ip_container_proxy_add_del_reply)
5312
5313 #define _(n)                                    \
5314     static void vl_api_##n##_t_handler          \
5315     (vl_api_##n##_t * mp)                       \
5316     {                                           \
5317         vat_main_t * vam = &vat_main;           \
5318         i32 retval = ntohl(mp->retval);         \
5319         if (vam->async_mode) {                  \
5320             vam->async_errors += (retval < 0);  \
5321         } else {                                \
5322             vam->retval = retval;               \
5323             vam->result_ready = 1;              \
5324         }                                       \
5325     }
5326 foreach_standard_reply_retval_handler;
5327 #undef _
5328
5329 #define _(n)                                    \
5330     static void vl_api_##n##_t_handler_json     \
5331     (vl_api_##n##_t * mp)                       \
5332     {                                           \
5333         vat_main_t * vam = &vat_main;           \
5334         vat_json_node_t node;                   \
5335         vat_json_init_object(&node);            \
5336         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5337         vat_json_print(vam->ofp, &node);        \
5338         vam->retval = ntohl(mp->retval);        \
5339         vam->result_ready = 1;                  \
5340     }
5341 foreach_standard_reply_retval_handler;
5342 #undef _
5343
5344 /*
5345  * Table of message reply handlers, must include boilerplate handlers
5346  * we just generated
5347  */
5348
5349 #define foreach_vpe_api_reply_msg                                       \
5350 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5351 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5352 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5353 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5354 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5355 _(CLI_REPLY, cli_reply)                                                 \
5356 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5357 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5358   sw_interface_add_del_address_reply)                                   \
5359 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5360 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5361 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5362 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5363 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5364 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5365 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5366 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5367   sw_interface_set_l2_xconnect_reply)                                   \
5368 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5369   sw_interface_set_l2_bridge_reply)                                     \
5370 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5371 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5372 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5373 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5374 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5375 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5376 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5377 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5378 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5379 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5380 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5381 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5382 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5383 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5384 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5385 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5386 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5387 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5388 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5389 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5390 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5391 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5392   proxy_arp_intfc_enable_disable_reply)                                 \
5393 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5394 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5395   sw_interface_set_unnumbered_reply)                                    \
5396 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5397 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5398 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5399 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5400 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5401 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5402 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5403 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5404 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5405 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5406 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5407 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5408   sw_interface_ip6_enable_disable_reply)                                \
5409 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5410   sw_interface_ip6_set_link_local_address_reply)                        \
5411 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5412 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5413 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5414   sw_interface_ip6nd_ra_prefix_reply)                                   \
5415 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5416   sw_interface_ip6nd_ra_config_reply)                                   \
5417 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5418 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5419 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5420 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5421 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5422 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5423 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5424 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5425 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5426 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5427 classify_set_interface_ip_table_reply)                                  \
5428 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5429   classify_set_interface_l2_tables_reply)                               \
5430 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5431 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5432 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5433 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5434 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5435   l2tpv3_interface_enable_disable_reply)                                \
5436 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5437 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5438 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5439 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5440 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5441 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5442 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5443 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5444 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5445 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5446 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5447 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5448 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5449 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5450 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5451 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5452 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5453 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5454 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5455 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5456 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5457 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5458 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5459 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5460 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5461 _(L2_MACS_EVENT, l2_macs_event)                                         \
5462 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5463 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5464 _(IP_DETAILS, ip_details)                                               \
5465 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5466 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5467 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5468 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5469 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5470 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5471 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5472 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5473 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5474 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5475 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5476 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5477 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5478 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5479 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5480 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5481 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5482 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5483 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5484 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5485 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5486 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5487 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5488 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5489 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5490 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5491 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5492 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5493 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5494 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5495 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5496 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5497 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5498 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5499 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5500 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5501 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5502 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5503 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5504 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5505 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5506 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5507 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5508 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5509 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5510 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5511 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5512 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5513   one_map_register_enable_disable_reply)                                \
5514 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5515 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5516 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5517 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5518   one_map_register_fallback_threshold_reply)                            \
5519 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5520   one_rloc_probe_enable_disable_reply)                                  \
5521 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5522 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5523 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5524 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5525 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5526 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5527 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5528 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5529 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5530 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5531 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5532 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5533 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5534 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5535 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5536 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5537   show_one_stats_enable_disable_reply)                                  \
5538 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5539 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5540 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5541 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5542 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5543 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5544 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5545 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5546   one_enable_disable_pitr_mode_reply)                                   \
5547 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5548   one_enable_disable_petr_mode_reply)                                   \
5549 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5550 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5551 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5552 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5553 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5554 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5555 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5556 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5557 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5558 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5559 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5560 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5561   gpe_add_del_native_fwd_rpath_reply)                                   \
5562 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5563   gpe_fwd_entry_path_details)                                           \
5564 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5565 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5566   one_add_del_map_request_itr_rlocs_reply)                              \
5567 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5568   one_get_map_request_itr_rlocs_reply)                                  \
5569 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5570 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5571 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5572 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5573 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5574 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5575   show_one_map_register_state_reply)                                    \
5576 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5577 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5578   show_one_map_register_fallback_threshold_reply)                       \
5579 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5580 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5581 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5582 _(POLICER_DETAILS, policer_details)                                     \
5583 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5584 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5585 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5586 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5587 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5588 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5589 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5590 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5591 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5592 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5593 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5594 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5595 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5596 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5597 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5598 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5599 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5600 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5601 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5602 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5603 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5604 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5605 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5606 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5607 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5608  ip_source_and_port_range_check_add_del_reply)                          \
5609 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5610  ip_source_and_port_range_check_interface_add_del_reply)                \
5611 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5612 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5613 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5614 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5615 _(PUNT_REPLY, punt_reply)                                               \
5616 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5617 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5618 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5619 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5620 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5621 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5622 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5623 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5624 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5625 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5626 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5627 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5628 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5629 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5630 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5631 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5632 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5633 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5634 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5635 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5636 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5637
5638 #define foreach_standalone_reply_msg                                    \
5639 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5640 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5641 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5642 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5643 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5644 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5645 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5646 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5647
5648 typedef struct
5649 {
5650   u8 *name;
5651   u32 value;
5652 } name_sort_t;
5653
5654
5655 #define STR_VTR_OP_CASE(op)     \
5656     case L2_VTR_ ## op:         \
5657         return "" # op;
5658
5659 static const char *
5660 str_vtr_op (u32 vtr_op)
5661 {
5662   switch (vtr_op)
5663     {
5664       STR_VTR_OP_CASE (DISABLED);
5665       STR_VTR_OP_CASE (PUSH_1);
5666       STR_VTR_OP_CASE (PUSH_2);
5667       STR_VTR_OP_CASE (POP_1);
5668       STR_VTR_OP_CASE (POP_2);
5669       STR_VTR_OP_CASE (TRANSLATE_1_1);
5670       STR_VTR_OP_CASE (TRANSLATE_1_2);
5671       STR_VTR_OP_CASE (TRANSLATE_2_1);
5672       STR_VTR_OP_CASE (TRANSLATE_2_2);
5673     }
5674
5675   return "UNKNOWN";
5676 }
5677
5678 static int
5679 dump_sub_interface_table (vat_main_t * vam)
5680 {
5681   const sw_interface_subif_t *sub = NULL;
5682
5683   if (vam->json_output)
5684     {
5685       clib_warning
5686         ("JSON output supported only for VPE API calls and dump_stats_table");
5687       return -99;
5688     }
5689
5690   print (vam->ofp,
5691          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5692          "Interface", "sw_if_index",
5693          "sub id", "dot1ad", "tags", "outer id",
5694          "inner id", "exact", "default", "outer any", "inner any");
5695
5696   vec_foreach (sub, vam->sw_if_subif_table)
5697   {
5698     print (vam->ofp,
5699            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5700            sub->interface_name,
5701            sub->sw_if_index,
5702            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5703            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5704            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5705            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5706     if (sub->vtr_op != L2_VTR_DISABLED)
5707       {
5708         print (vam->ofp,
5709                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5710                "tag1: %d tag2: %d ]",
5711                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5712                sub->vtr_tag1, sub->vtr_tag2);
5713       }
5714   }
5715
5716   return 0;
5717 }
5718
5719 static int
5720 name_sort_cmp (void *a1, void *a2)
5721 {
5722   name_sort_t *n1 = a1;
5723   name_sort_t *n2 = a2;
5724
5725   return strcmp ((char *) n1->name, (char *) n2->name);
5726 }
5727
5728 static int
5729 dump_interface_table (vat_main_t * vam)
5730 {
5731   hash_pair_t *p;
5732   name_sort_t *nses = 0, *ns;
5733
5734   if (vam->json_output)
5735     {
5736       clib_warning
5737         ("JSON output supported only for VPE API calls and dump_stats_table");
5738       return -99;
5739     }
5740
5741   /* *INDENT-OFF* */
5742   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5743   ({
5744     vec_add2 (nses, ns, 1);
5745     ns->name = (u8 *)(p->key);
5746     ns->value = (u32) p->value[0];
5747   }));
5748   /* *INDENT-ON* */
5749
5750   vec_sort_with_function (nses, name_sort_cmp);
5751
5752   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5753   vec_foreach (ns, nses)
5754   {
5755     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5756   }
5757   vec_free (nses);
5758   return 0;
5759 }
5760
5761 static int
5762 dump_ip_table (vat_main_t * vam, int is_ipv6)
5763 {
5764   const ip_details_t *det = NULL;
5765   const ip_address_details_t *address = NULL;
5766   u32 i = ~0;
5767
5768   print (vam->ofp, "%-12s", "sw_if_index");
5769
5770   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5771   {
5772     i++;
5773     if (!det->present)
5774       {
5775         continue;
5776       }
5777     print (vam->ofp, "%-12d", i);
5778     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5779     if (!det->addr)
5780       {
5781         continue;
5782       }
5783     vec_foreach (address, det->addr)
5784     {
5785       print (vam->ofp,
5786              "            %-30U%-13d",
5787              is_ipv6 ? format_ip6_address : format_ip4_address,
5788              address->ip, address->prefix_length);
5789     }
5790   }
5791
5792   return 0;
5793 }
5794
5795 static int
5796 dump_ipv4_table (vat_main_t * vam)
5797 {
5798   if (vam->json_output)
5799     {
5800       clib_warning
5801         ("JSON output supported only for VPE API calls and dump_stats_table");
5802       return -99;
5803     }
5804
5805   return dump_ip_table (vam, 0);
5806 }
5807
5808 static int
5809 dump_ipv6_table (vat_main_t * vam)
5810 {
5811   if (vam->json_output)
5812     {
5813       clib_warning
5814         ("JSON output supported only for VPE API calls and dump_stats_table");
5815       return -99;
5816     }
5817
5818   return dump_ip_table (vam, 1);
5819 }
5820
5821 static char *
5822 counter_type_to_str (u8 counter_type, u8 is_combined)
5823 {
5824   if (!is_combined)
5825     {
5826       switch (counter_type)
5827         {
5828         case VNET_INTERFACE_COUNTER_DROP:
5829           return "drop";
5830         case VNET_INTERFACE_COUNTER_PUNT:
5831           return "punt";
5832         case VNET_INTERFACE_COUNTER_IP4:
5833           return "ip4";
5834         case VNET_INTERFACE_COUNTER_IP6:
5835           return "ip6";
5836         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5837           return "rx-no-buf";
5838         case VNET_INTERFACE_COUNTER_RX_MISS:
5839           return "rx-miss";
5840         case VNET_INTERFACE_COUNTER_RX_ERROR:
5841           return "rx-error";
5842         case VNET_INTERFACE_COUNTER_TX_ERROR:
5843           return "tx-error";
5844         default:
5845           return "INVALID-COUNTER-TYPE";
5846         }
5847     }
5848   else
5849     {
5850       switch (counter_type)
5851         {
5852         case VNET_INTERFACE_COUNTER_RX:
5853           return "rx";
5854         case VNET_INTERFACE_COUNTER_TX:
5855           return "tx";
5856         default:
5857           return "INVALID-COUNTER-TYPE";
5858         }
5859     }
5860 }
5861
5862 static int
5863 dump_stats_table (vat_main_t * vam)
5864 {
5865   vat_json_node_t node;
5866   vat_json_node_t *msg_array;
5867   vat_json_node_t *msg;
5868   vat_json_node_t *counter_array;
5869   vat_json_node_t *counter;
5870   interface_counter_t c;
5871   u64 packets;
5872   ip4_fib_counter_t *c4;
5873   ip6_fib_counter_t *c6;
5874   ip4_nbr_counter_t *n4;
5875   ip6_nbr_counter_t *n6;
5876   int i, j;
5877
5878   if (!vam->json_output)
5879     {
5880       clib_warning ("dump_stats_table supported only in JSON format");
5881       return -99;
5882     }
5883
5884   vat_json_init_object (&node);
5885
5886   /* interface counters */
5887   msg_array = vat_json_object_add (&node, "interface_counters");
5888   vat_json_init_array (msg_array);
5889   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5890     {
5891       msg = vat_json_array_add (msg_array);
5892       vat_json_init_object (msg);
5893       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5894                                        (u8 *) counter_type_to_str (i, 0));
5895       vat_json_object_add_int (msg, "is_combined", 0);
5896       counter_array = vat_json_object_add (msg, "data");
5897       vat_json_init_array (counter_array);
5898       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5899         {
5900           packets = vam->simple_interface_counters[i][j];
5901           vat_json_array_add_uint (counter_array, packets);
5902         }
5903     }
5904   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5905     {
5906       msg = vat_json_array_add (msg_array);
5907       vat_json_init_object (msg);
5908       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5909                                        (u8 *) counter_type_to_str (i, 1));
5910       vat_json_object_add_int (msg, "is_combined", 1);
5911       counter_array = vat_json_object_add (msg, "data");
5912       vat_json_init_array (counter_array);
5913       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5914         {
5915           c = vam->combined_interface_counters[i][j];
5916           counter = vat_json_array_add (counter_array);
5917           vat_json_init_object (counter);
5918           vat_json_object_add_uint (counter, "packets", c.packets);
5919           vat_json_object_add_uint (counter, "bytes", c.bytes);
5920         }
5921     }
5922
5923   /* ip4 fib counters */
5924   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5925   vat_json_init_array (msg_array);
5926   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5927     {
5928       msg = vat_json_array_add (msg_array);
5929       vat_json_init_object (msg);
5930       vat_json_object_add_uint (msg, "vrf_id",
5931                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5932       counter_array = vat_json_object_add (msg, "c");
5933       vat_json_init_array (counter_array);
5934       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5935         {
5936           counter = vat_json_array_add (counter_array);
5937           vat_json_init_object (counter);
5938           c4 = &vam->ip4_fib_counters[i][j];
5939           vat_json_object_add_ip4 (counter, "address", c4->address);
5940           vat_json_object_add_uint (counter, "address_length",
5941                                     c4->address_length);
5942           vat_json_object_add_uint (counter, "packets", c4->packets);
5943           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5944         }
5945     }
5946
5947   /* ip6 fib counters */
5948   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5949   vat_json_init_array (msg_array);
5950   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5951     {
5952       msg = vat_json_array_add (msg_array);
5953       vat_json_init_object (msg);
5954       vat_json_object_add_uint (msg, "vrf_id",
5955                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5956       counter_array = vat_json_object_add (msg, "c");
5957       vat_json_init_array (counter_array);
5958       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5959         {
5960           counter = vat_json_array_add (counter_array);
5961           vat_json_init_object (counter);
5962           c6 = &vam->ip6_fib_counters[i][j];
5963           vat_json_object_add_ip6 (counter, "address", c6->address);
5964           vat_json_object_add_uint (counter, "address_length",
5965                                     c6->address_length);
5966           vat_json_object_add_uint (counter, "packets", c6->packets);
5967           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5968         }
5969     }
5970
5971   /* ip4 nbr counters */
5972   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5973   vat_json_init_array (msg_array);
5974   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5975     {
5976       msg = vat_json_array_add (msg_array);
5977       vat_json_init_object (msg);
5978       vat_json_object_add_uint (msg, "sw_if_index", i);
5979       counter_array = vat_json_object_add (msg, "c");
5980       vat_json_init_array (counter_array);
5981       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5982         {
5983           counter = vat_json_array_add (counter_array);
5984           vat_json_init_object (counter);
5985           n4 = &vam->ip4_nbr_counters[i][j];
5986           vat_json_object_add_ip4 (counter, "address", n4->address);
5987           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5988           vat_json_object_add_uint (counter, "packets", n4->packets);
5989           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5990         }
5991     }
5992
5993   /* ip6 nbr counters */
5994   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5995   vat_json_init_array (msg_array);
5996   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5997     {
5998       msg = vat_json_array_add (msg_array);
5999       vat_json_init_object (msg);
6000       vat_json_object_add_uint (msg, "sw_if_index", i);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           n6 = &vam->ip6_nbr_counters[i][j];
6008           vat_json_object_add_ip6 (counter, "address", n6->address);
6009           vat_json_object_add_uint (counter, "packets", n6->packets);
6010           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6011         }
6012     }
6013
6014   vat_json_print (vam->ofp, &node);
6015   vat_json_free (&node);
6016
6017   return 0;
6018 }
6019
6020 /*
6021  * Pass CLI buffers directly in the CLI_INBAND API message,
6022  * instead of an additional shared memory area.
6023  */
6024 static int
6025 exec_inband (vat_main_t * vam)
6026 {
6027   vl_api_cli_inband_t *mp;
6028   unformat_input_t *i = vam->input;
6029   int ret;
6030
6031   if (vec_len (i->buffer) == 0)
6032     return -1;
6033
6034   if (vam->exec_mode == 0 && unformat (i, "mode"))
6035     {
6036       vam->exec_mode = 1;
6037       return 0;
6038     }
6039   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6040     {
6041       vam->exec_mode = 0;
6042       return 0;
6043     }
6044
6045   /*
6046    * In order for the CLI command to work, it
6047    * must be a vector ending in \n, not a C-string ending
6048    * in \n\0.
6049    */
6050   u32 len = vec_len (vam->input->buffer);
6051   M2 (CLI_INBAND, mp, len);
6052   clib_memcpy (mp->cmd, vam->input->buffer, len);
6053   mp->length = htonl (len);
6054
6055   S (mp);
6056   W (ret);
6057   /* json responses may or may not include a useful reply... */
6058   if (vec_len (vam->cmd_reply))
6059     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6060   return ret;
6061 }
6062
6063 int
6064 exec (vat_main_t * vam)
6065 {
6066   return exec_inband (vam);
6067 }
6068
6069 static int
6070 api_create_loopback (vat_main_t * vam)
6071 {
6072   unformat_input_t *i = vam->input;
6073   vl_api_create_loopback_t *mp;
6074   vl_api_create_loopback_instance_t *mp_lbi;
6075   u8 mac_address[6];
6076   u8 mac_set = 0;
6077   u8 is_specified = 0;
6078   u32 user_instance = 0;
6079   int ret;
6080
6081   memset (mac_address, 0, sizeof (mac_address));
6082
6083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6084     {
6085       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6086         mac_set = 1;
6087       if (unformat (i, "instance %d", &user_instance))
6088         is_specified = 1;
6089       else
6090         break;
6091     }
6092
6093   if (is_specified)
6094     {
6095       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6096       mp_lbi->is_specified = is_specified;
6097       if (is_specified)
6098         mp_lbi->user_instance = htonl (user_instance);
6099       if (mac_set)
6100         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6101       S (mp_lbi);
6102     }
6103   else
6104     {
6105       /* Construct the API message */
6106       M (CREATE_LOOPBACK, mp);
6107       if (mac_set)
6108         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6109       S (mp);
6110     }
6111
6112   W (ret);
6113   return ret;
6114 }
6115
6116 static int
6117 api_delete_loopback (vat_main_t * vam)
6118 {
6119   unformat_input_t *i = vam->input;
6120   vl_api_delete_loopback_t *mp;
6121   u32 sw_if_index = ~0;
6122   int ret;
6123
6124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125     {
6126       if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         ;
6128       else
6129         break;
6130     }
6131
6132   if (sw_if_index == ~0)
6133     {
6134       errmsg ("missing sw_if_index");
6135       return -99;
6136     }
6137
6138   /* Construct the API message */
6139   M (DELETE_LOOPBACK, mp);
6140   mp->sw_if_index = ntohl (sw_if_index);
6141
6142   S (mp);
6143   W (ret);
6144   return ret;
6145 }
6146
6147 static int
6148 api_want_stats (vat_main_t * vam)
6149 {
6150   unformat_input_t *i = vam->input;
6151   vl_api_want_stats_t *mp;
6152   int enable = -1;
6153   int ret;
6154
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "enable"))
6158         enable = 1;
6159       else if (unformat (i, "disable"))
6160         enable = 0;
6161       else
6162         break;
6163     }
6164
6165   if (enable == -1)
6166     {
6167       errmsg ("missing enable|disable");
6168       return -99;
6169     }
6170
6171   M (WANT_STATS, mp);
6172   mp->enable_disable = enable;
6173
6174   S (mp);
6175   W (ret);
6176   return ret;
6177 }
6178
6179 static int
6180 api_want_interface_events (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_want_interface_events_t *mp;
6184   int enable = -1;
6185   int ret;
6186
6187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6188     {
6189       if (unformat (i, "enable"))
6190         enable = 1;
6191       else if (unformat (i, "disable"))
6192         enable = 0;
6193       else
6194         break;
6195     }
6196
6197   if (enable == -1)
6198     {
6199       errmsg ("missing enable|disable");
6200       return -99;
6201     }
6202
6203   M (WANT_INTERFACE_EVENTS, mp);
6204   mp->enable_disable = enable;
6205
6206   vam->interface_event_display = enable;
6207
6208   S (mp);
6209   W (ret);
6210   return ret;
6211 }
6212
6213
6214 /* Note: non-static, called once to set up the initial intfc table */
6215 int
6216 api_sw_interface_dump (vat_main_t * vam)
6217 {
6218   vl_api_sw_interface_dump_t *mp;
6219   vl_api_control_ping_t *mp_ping;
6220   hash_pair_t *p;
6221   name_sort_t *nses = 0, *ns;
6222   sw_interface_subif_t *sub = NULL;
6223   int ret;
6224
6225   /* Toss the old name table */
6226   /* *INDENT-OFF* */
6227   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6228   ({
6229     vec_add2 (nses, ns, 1);
6230     ns->name = (u8 *)(p->key);
6231     ns->value = (u32) p->value[0];
6232   }));
6233   /* *INDENT-ON* */
6234
6235   hash_free (vam->sw_if_index_by_interface_name);
6236
6237   vec_foreach (ns, nses) vec_free (ns->name);
6238
6239   vec_free (nses);
6240
6241   vec_foreach (sub, vam->sw_if_subif_table)
6242   {
6243     vec_free (sub->interface_name);
6244   }
6245   vec_free (vam->sw_if_subif_table);
6246
6247   /* recreate the interface name hash table */
6248   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6249
6250   /* Get list of ethernets */
6251   M (SW_INTERFACE_DUMP, mp);
6252   mp->name_filter_valid = 1;
6253   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6254   S (mp);
6255
6256   /* and local / loopback interfaces */
6257   M (SW_INTERFACE_DUMP, mp);
6258   mp->name_filter_valid = 1;
6259   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6260   S (mp);
6261
6262   /* and packet-generator interfaces */
6263   M (SW_INTERFACE_DUMP, mp);
6264   mp->name_filter_valid = 1;
6265   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6266   S (mp);
6267
6268   /* and vxlan-gpe tunnel interfaces */
6269   M (SW_INTERFACE_DUMP, mp);
6270   mp->name_filter_valid = 1;
6271   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6272            sizeof (mp->name_filter) - 1);
6273   S (mp);
6274
6275   /* and vxlan tunnel interfaces */
6276   M (SW_INTERFACE_DUMP, mp);
6277   mp->name_filter_valid = 1;
6278   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6279   S (mp);
6280
6281   /* and geneve tunnel interfaces */
6282   M (SW_INTERFACE_DUMP, mp);
6283   mp->name_filter_valid = 1;
6284   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6285   S (mp);
6286
6287   /* and host (af_packet) interfaces */
6288   M (SW_INTERFACE_DUMP, mp);
6289   mp->name_filter_valid = 1;
6290   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6291   S (mp);
6292
6293   /* and l2tpv3 tunnel interfaces */
6294   M (SW_INTERFACE_DUMP, mp);
6295   mp->name_filter_valid = 1;
6296   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6297            sizeof (mp->name_filter) - 1);
6298   S (mp);
6299
6300   /* and GRE tunnel interfaces */
6301   M (SW_INTERFACE_DUMP, mp);
6302   mp->name_filter_valid = 1;
6303   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6304   S (mp);
6305
6306   /* and LISP-GPE interfaces */
6307   M (SW_INTERFACE_DUMP, mp);
6308   mp->name_filter_valid = 1;
6309   strncpy ((char *) mp->name_filter, "lisp_gpe",
6310            sizeof (mp->name_filter) - 1);
6311   S (mp);
6312
6313   /* and IPSEC tunnel interfaces */
6314   M (SW_INTERFACE_DUMP, mp);
6315   mp->name_filter_valid = 1;
6316   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6317   S (mp);
6318
6319   /* Use a control ping for synchronization */
6320   MPING (CONTROL_PING, mp_ping);
6321   S (mp_ping);
6322
6323   W (ret);
6324   return ret;
6325 }
6326
6327 static int
6328 api_sw_interface_set_flags (vat_main_t * vam)
6329 {
6330   unformat_input_t *i = vam->input;
6331   vl_api_sw_interface_set_flags_t *mp;
6332   u32 sw_if_index;
6333   u8 sw_if_index_set = 0;
6334   u8 admin_up = 0;
6335   int ret;
6336
6337   /* Parse args required to build the message */
6338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6339     {
6340       if (unformat (i, "admin-up"))
6341         admin_up = 1;
6342       else if (unformat (i, "admin-down"))
6343         admin_up = 0;
6344       else
6345         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6348         sw_if_index_set = 1;
6349       else
6350         break;
6351     }
6352
6353   if (sw_if_index_set == 0)
6354     {
6355       errmsg ("missing interface name or sw_if_index");
6356       return -99;
6357     }
6358
6359   /* Construct the API message */
6360   M (SW_INTERFACE_SET_FLAGS, mp);
6361   mp->sw_if_index = ntohl (sw_if_index);
6362   mp->admin_up_down = admin_up;
6363
6364   /* send it... */
6365   S (mp);
6366
6367   /* Wait for a reply, return the good/bad news... */
6368   W (ret);
6369   return ret;
6370 }
6371
6372 static int
6373 api_sw_interface_set_rx_mode (vat_main_t * vam)
6374 {
6375   unformat_input_t *i = vam->input;
6376   vl_api_sw_interface_set_rx_mode_t *mp;
6377   u32 sw_if_index;
6378   u8 sw_if_index_set = 0;
6379   int ret;
6380   u8 queue_id_valid = 0;
6381   u32 queue_id;
6382   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6383
6384   /* Parse args required to build the message */
6385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6386     {
6387       if (unformat (i, "queue %d", &queue_id))
6388         queue_id_valid = 1;
6389       else if (unformat (i, "polling"))
6390         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6391       else if (unformat (i, "interrupt"))
6392         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6393       else if (unformat (i, "adaptive"))
6394         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6395       else
6396         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6397         sw_if_index_set = 1;
6398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6399         sw_if_index_set = 1;
6400       else
6401         break;
6402     }
6403
6404   if (sw_if_index_set == 0)
6405     {
6406       errmsg ("missing interface name or sw_if_index");
6407       return -99;
6408     }
6409   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6410     {
6411       errmsg ("missing rx-mode");
6412       return -99;
6413     }
6414
6415   /* Construct the API message */
6416   M (SW_INTERFACE_SET_RX_MODE, mp);
6417   mp->sw_if_index = ntohl (sw_if_index);
6418   mp->mode = mode;
6419   mp->queue_id_valid = queue_id_valid;
6420   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6421
6422   /* send it... */
6423   S (mp);
6424
6425   /* Wait for a reply, return the good/bad news... */
6426   W (ret);
6427   return ret;
6428 }
6429
6430 static int
6431 api_sw_interface_clear_stats (vat_main_t * vam)
6432 {
6433   unformat_input_t *i = vam->input;
6434   vl_api_sw_interface_clear_stats_t *mp;
6435   u32 sw_if_index;
6436   u8 sw_if_index_set = 0;
6437   int ret;
6438
6439   /* Parse args required to build the message */
6440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6441     {
6442       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6445         sw_if_index_set = 1;
6446       else
6447         break;
6448     }
6449
6450   /* Construct the API message */
6451   M (SW_INTERFACE_CLEAR_STATS, mp);
6452
6453   if (sw_if_index_set == 1)
6454     mp->sw_if_index = ntohl (sw_if_index);
6455   else
6456     mp->sw_if_index = ~0;
6457
6458   /* send it... */
6459   S (mp);
6460
6461   /* Wait for a reply, return the good/bad news... */
6462   W (ret);
6463   return ret;
6464 }
6465
6466 static int
6467 api_sw_interface_add_del_address (vat_main_t * vam)
6468 {
6469   unformat_input_t *i = vam->input;
6470   vl_api_sw_interface_add_del_address_t *mp;
6471   u32 sw_if_index;
6472   u8 sw_if_index_set = 0;
6473   u8 is_add = 1, del_all = 0;
6474   u32 address_length = 0;
6475   u8 v4_address_set = 0;
6476   u8 v6_address_set = 0;
6477   ip4_address_t v4address;
6478   ip6_address_t v6address;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "del-all"))
6485         del_all = 1;
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else
6489         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6490         sw_if_index_set = 1;
6491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6492         sw_if_index_set = 1;
6493       else if (unformat (i, "%U/%d",
6494                          unformat_ip4_address, &v4address, &address_length))
6495         v4_address_set = 1;
6496       else if (unformat (i, "%U/%d",
6497                          unformat_ip6_address, &v6address, &address_length))
6498         v6_address_set = 1;
6499       else
6500         break;
6501     }
6502
6503   if (sw_if_index_set == 0)
6504     {
6505       errmsg ("missing interface name or sw_if_index");
6506       return -99;
6507     }
6508   if (v4_address_set && v6_address_set)
6509     {
6510       errmsg ("both v4 and v6 addresses set");
6511       return -99;
6512     }
6513   if (!v4_address_set && !v6_address_set && !del_all)
6514     {
6515       errmsg ("no addresses set");
6516       return -99;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6521
6522   mp->sw_if_index = ntohl (sw_if_index);
6523   mp->is_add = is_add;
6524   mp->del_all = del_all;
6525   if (v6_address_set)
6526     {
6527       mp->is_ipv6 = 1;
6528       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6529     }
6530   else
6531     {
6532       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6533     }
6534   mp->address_length = address_length;
6535
6536   /* send it... */
6537   S (mp);
6538
6539   /* Wait for a reply, return good/bad news  */
6540   W (ret);
6541   return ret;
6542 }
6543
6544 static int
6545 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6546 {
6547   unformat_input_t *i = vam->input;
6548   vl_api_sw_interface_set_mpls_enable_t *mp;
6549   u32 sw_if_index;
6550   u8 sw_if_index_set = 0;
6551   u8 enable = 1;
6552   int ret;
6553
6554   /* Parse args required to build the message */
6555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6556     {
6557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6558         sw_if_index_set = 1;
6559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6560         sw_if_index_set = 1;
6561       else if (unformat (i, "disable"))
6562         enable = 0;
6563       else if (unformat (i, "dis"))
6564         enable = 0;
6565       else
6566         break;
6567     }
6568
6569   if (sw_if_index_set == 0)
6570     {
6571       errmsg ("missing interface name or sw_if_index");
6572       return -99;
6573     }
6574
6575   /* Construct the API message */
6576   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6577
6578   mp->sw_if_index = ntohl (sw_if_index);
6579   mp->enable = enable;
6580
6581   /* send it... */
6582   S (mp);
6583
6584   /* Wait for a reply... */
6585   W (ret);
6586   return ret;
6587 }
6588
6589 static int
6590 api_sw_interface_set_table (vat_main_t * vam)
6591 {
6592   unformat_input_t *i = vam->input;
6593   vl_api_sw_interface_set_table_t *mp;
6594   u32 sw_if_index, vrf_id = 0;
6595   u8 sw_if_index_set = 0;
6596   u8 is_ipv6 = 0;
6597   int ret;
6598
6599   /* Parse args required to build the message */
6600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6601     {
6602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6603         sw_if_index_set = 1;
6604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6605         sw_if_index_set = 1;
6606       else if (unformat (i, "vrf %d", &vrf_id))
6607         ;
6608       else if (unformat (i, "ipv6"))
6609         is_ipv6 = 1;
6610       else
6611         break;
6612     }
6613
6614   if (sw_if_index_set == 0)
6615     {
6616       errmsg ("missing interface name or sw_if_index");
6617       return -99;
6618     }
6619
6620   /* Construct the API message */
6621   M (SW_INTERFACE_SET_TABLE, mp);
6622
6623   mp->sw_if_index = ntohl (sw_if_index);
6624   mp->is_ipv6 = is_ipv6;
6625   mp->vrf_id = ntohl (vrf_id);
6626
6627   /* send it... */
6628   S (mp);
6629
6630   /* Wait for a reply... */
6631   W (ret);
6632   return ret;
6633 }
6634
6635 static void vl_api_sw_interface_get_table_reply_t_handler
6636   (vl_api_sw_interface_get_table_reply_t * mp)
6637 {
6638   vat_main_t *vam = &vat_main;
6639
6640   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6641
6642   vam->retval = ntohl (mp->retval);
6643   vam->result_ready = 1;
6644
6645 }
6646
6647 static void vl_api_sw_interface_get_table_reply_t_handler_json
6648   (vl_api_sw_interface_get_table_reply_t * mp)
6649 {
6650   vat_main_t *vam = &vat_main;
6651   vat_json_node_t node;
6652
6653   vat_json_init_object (&node);
6654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6655   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6656
6657   vat_json_print (vam->ofp, &node);
6658   vat_json_free (&node);
6659
6660   vam->retval = ntohl (mp->retval);
6661   vam->result_ready = 1;
6662 }
6663
6664 static int
6665 api_sw_interface_get_table (vat_main_t * vam)
6666 {
6667   unformat_input_t *i = vam->input;
6668   vl_api_sw_interface_get_table_t *mp;
6669   u32 sw_if_index;
6670   u8 sw_if_index_set = 0;
6671   u8 is_ipv6 = 0;
6672   int ret;
6673
6674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675     {
6676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "ipv6"))
6681         is_ipv6 = 1;
6682       else
6683         break;
6684     }
6685
6686   if (sw_if_index_set == 0)
6687     {
6688       errmsg ("missing interface name or sw_if_index");
6689       return -99;
6690     }
6691
6692   M (SW_INTERFACE_GET_TABLE, mp);
6693   mp->sw_if_index = htonl (sw_if_index);
6694   mp->is_ipv6 = is_ipv6;
6695
6696   S (mp);
6697   W (ret);
6698   return ret;
6699 }
6700
6701 static int
6702 api_sw_interface_set_vpath (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_set_vpath_t *mp;
6706   u32 sw_if_index = 0;
6707   u8 sw_if_index_set = 0;
6708   u8 is_enable = 0;
6709   int ret;
6710
6711   /* Parse args required to build the message */
6712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6713     {
6714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6717         sw_if_index_set = 1;
6718       else if (unformat (i, "enable"))
6719         is_enable = 1;
6720       else if (unformat (i, "disable"))
6721         is_enable = 0;
6722       else
6723         break;
6724     }
6725
6726   if (sw_if_index_set == 0)
6727     {
6728       errmsg ("missing interface name or sw_if_index");
6729       return -99;
6730     }
6731
6732   /* Construct the API message */
6733   M (SW_INTERFACE_SET_VPATH, mp);
6734
6735   mp->sw_if_index = ntohl (sw_if_index);
6736   mp->enable = is_enable;
6737
6738   /* send it... */
6739   S (mp);
6740
6741   /* Wait for a reply... */
6742   W (ret);
6743   return ret;
6744 }
6745
6746 static int
6747 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6748 {
6749   unformat_input_t *i = vam->input;
6750   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6751   u32 sw_if_index = 0;
6752   u8 sw_if_index_set = 0;
6753   u8 is_enable = 1;
6754   u8 is_ipv6 = 0;
6755   int ret;
6756
6757   /* Parse args required to build the message */
6758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6759     {
6760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6763         sw_if_index_set = 1;
6764       else if (unformat (i, "enable"))
6765         is_enable = 1;
6766       else if (unformat (i, "disable"))
6767         is_enable = 0;
6768       else if (unformat (i, "ip4"))
6769         is_ipv6 = 0;
6770       else if (unformat (i, "ip6"))
6771         is_ipv6 = 1;
6772       else
6773         break;
6774     }
6775
6776   if (sw_if_index_set == 0)
6777     {
6778       errmsg ("missing interface name or sw_if_index");
6779       return -99;
6780     }
6781
6782   /* Construct the API message */
6783   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6784
6785   mp->sw_if_index = ntohl (sw_if_index);
6786   mp->enable = is_enable;
6787   mp->is_ipv6 = is_ipv6;
6788
6789   /* send it... */
6790   S (mp);
6791
6792   /* Wait for a reply... */
6793   W (ret);
6794   return ret;
6795 }
6796
6797 static int
6798 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6799 {
6800   unformat_input_t *i = vam->input;
6801   vl_api_sw_interface_set_geneve_bypass_t *mp;
6802   u32 sw_if_index = 0;
6803   u8 sw_if_index_set = 0;
6804   u8 is_enable = 1;
6805   u8 is_ipv6 = 0;
6806   int ret;
6807
6808   /* Parse args required to build the message */
6809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6810     {
6811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6812         sw_if_index_set = 1;
6813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6814         sw_if_index_set = 1;
6815       else if (unformat (i, "enable"))
6816         is_enable = 1;
6817       else if (unformat (i, "disable"))
6818         is_enable = 0;
6819       else if (unformat (i, "ip4"))
6820         is_ipv6 = 0;
6821       else if (unformat (i, "ip6"))
6822         is_ipv6 = 1;
6823       else
6824         break;
6825     }
6826
6827   if (sw_if_index_set == 0)
6828     {
6829       errmsg ("missing interface name or sw_if_index");
6830       return -99;
6831     }
6832
6833   /* Construct the API message */
6834   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6835
6836   mp->sw_if_index = ntohl (sw_if_index);
6837   mp->enable = is_enable;
6838   mp->is_ipv6 = is_ipv6;
6839
6840   /* send it... */
6841   S (mp);
6842
6843   /* Wait for a reply... */
6844   W (ret);
6845   return ret;
6846 }
6847
6848 static int
6849 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6850 {
6851   unformat_input_t *i = vam->input;
6852   vl_api_sw_interface_set_l2_xconnect_t *mp;
6853   u32 rx_sw_if_index;
6854   u8 rx_sw_if_index_set = 0;
6855   u32 tx_sw_if_index;
6856   u8 tx_sw_if_index_set = 0;
6857   u8 enable = 1;
6858   int ret;
6859
6860   /* Parse args required to build the message */
6861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6862     {
6863       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6864         rx_sw_if_index_set = 1;
6865       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6866         tx_sw_if_index_set = 1;
6867       else if (unformat (i, "rx"))
6868         {
6869           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6870             {
6871               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6872                             &rx_sw_if_index))
6873                 rx_sw_if_index_set = 1;
6874             }
6875           else
6876             break;
6877         }
6878       else if (unformat (i, "tx"))
6879         {
6880           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881             {
6882               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6883                             &tx_sw_if_index))
6884                 tx_sw_if_index_set = 1;
6885             }
6886           else
6887             break;
6888         }
6889       else if (unformat (i, "enable"))
6890         enable = 1;
6891       else if (unformat (i, "disable"))
6892         enable = 0;
6893       else
6894         break;
6895     }
6896
6897   if (rx_sw_if_index_set == 0)
6898     {
6899       errmsg ("missing rx interface name or rx_sw_if_index");
6900       return -99;
6901     }
6902
6903   if (enable && (tx_sw_if_index_set == 0))
6904     {
6905       errmsg ("missing tx interface name or tx_sw_if_index");
6906       return -99;
6907     }
6908
6909   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6910
6911   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6912   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6913   mp->enable = enable;
6914
6915   S (mp);
6916   W (ret);
6917   return ret;
6918 }
6919
6920 static int
6921 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6922 {
6923   unformat_input_t *i = vam->input;
6924   vl_api_sw_interface_set_l2_bridge_t *mp;
6925   u32 rx_sw_if_index;
6926   u8 rx_sw_if_index_set = 0;
6927   u32 bd_id;
6928   u8 bd_id_set = 0;
6929   u8 bvi = 0;
6930   u32 shg = 0;
6931   u8 enable = 1;
6932   int ret;
6933
6934   /* Parse args required to build the message */
6935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6936     {
6937       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6938         rx_sw_if_index_set = 1;
6939       else if (unformat (i, "bd_id %d", &bd_id))
6940         bd_id_set = 1;
6941       else
6942         if (unformat
6943             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6944         rx_sw_if_index_set = 1;
6945       else if (unformat (i, "shg %d", &shg))
6946         ;
6947       else if (unformat (i, "bvi"))
6948         bvi = 1;
6949       else if (unformat (i, "enable"))
6950         enable = 1;
6951       else if (unformat (i, "disable"))
6952         enable = 0;
6953       else
6954         break;
6955     }
6956
6957   if (rx_sw_if_index_set == 0)
6958     {
6959       errmsg ("missing rx interface name or sw_if_index");
6960       return -99;
6961     }
6962
6963   if (enable && (bd_id_set == 0))
6964     {
6965       errmsg ("missing bridge domain");
6966       return -99;
6967     }
6968
6969   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6970
6971   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6972   mp->bd_id = ntohl (bd_id);
6973   mp->shg = (u8) shg;
6974   mp->bvi = bvi;
6975   mp->enable = enable;
6976
6977   S (mp);
6978   W (ret);
6979   return ret;
6980 }
6981
6982 static int
6983 api_bridge_domain_dump (vat_main_t * vam)
6984 {
6985   unformat_input_t *i = vam->input;
6986   vl_api_bridge_domain_dump_t *mp;
6987   vl_api_control_ping_t *mp_ping;
6988   u32 bd_id = ~0;
6989   int ret;
6990
6991   /* Parse args required to build the message */
6992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993     {
6994       if (unformat (i, "bd_id %d", &bd_id))
6995         ;
6996       else
6997         break;
6998     }
6999
7000   M (BRIDGE_DOMAIN_DUMP, mp);
7001   mp->bd_id = ntohl (bd_id);
7002   S (mp);
7003
7004   /* Use a control ping for synchronization */
7005   MPING (CONTROL_PING, mp_ping);
7006   S (mp_ping);
7007
7008   W (ret);
7009   return ret;
7010 }
7011
7012 static int
7013 api_bridge_domain_add_del (vat_main_t * vam)
7014 {
7015   unformat_input_t *i = vam->input;
7016   vl_api_bridge_domain_add_del_t *mp;
7017   u32 bd_id = ~0;
7018   u8 is_add = 1;
7019   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7020   u8 *bd_tag = NULL;
7021   u32 mac_age = 0;
7022   int ret;
7023
7024   /* Parse args required to build the message */
7025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7026     {
7027       if (unformat (i, "bd_id %d", &bd_id))
7028         ;
7029       else if (unformat (i, "flood %d", &flood))
7030         ;
7031       else if (unformat (i, "uu-flood %d", &uu_flood))
7032         ;
7033       else if (unformat (i, "forward %d", &forward))
7034         ;
7035       else if (unformat (i, "learn %d", &learn))
7036         ;
7037       else if (unformat (i, "arp-term %d", &arp_term))
7038         ;
7039       else if (unformat (i, "mac-age %d", &mac_age))
7040         ;
7041       else if (unformat (i, "bd-tag %s", &bd_tag))
7042         ;
7043       else if (unformat (i, "del"))
7044         {
7045           is_add = 0;
7046           flood = uu_flood = forward = learn = 0;
7047         }
7048       else
7049         break;
7050     }
7051
7052   if (bd_id == ~0)
7053     {
7054       errmsg ("missing bridge domain");
7055       ret = -99;
7056       goto done;
7057     }
7058
7059   if (mac_age > 255)
7060     {
7061       errmsg ("mac age must be less than 256 ");
7062       ret = -99;
7063       goto done;
7064     }
7065
7066   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7067     {
7068       errmsg ("bd-tag cannot be longer than 63");
7069       ret = -99;
7070       goto done;
7071     }
7072
7073   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7074
7075   mp->bd_id = ntohl (bd_id);
7076   mp->flood = flood;
7077   mp->uu_flood = uu_flood;
7078   mp->forward = forward;
7079   mp->learn = learn;
7080   mp->arp_term = arp_term;
7081   mp->is_add = is_add;
7082   mp->mac_age = (u8) mac_age;
7083   if (bd_tag)
7084     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7085
7086   S (mp);
7087   W (ret);
7088
7089 done:
7090   vec_free (bd_tag);
7091   return ret;
7092 }
7093
7094 static int
7095 api_l2fib_flush_bd (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_l2fib_flush_bd_t *mp;
7099   u32 bd_id = ~0;
7100   int ret;
7101
7102   /* Parse args required to build the message */
7103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7104     {
7105       if (unformat (i, "bd_id %d", &bd_id));
7106       else
7107         break;
7108     }
7109
7110   if (bd_id == ~0)
7111     {
7112       errmsg ("missing bridge domain");
7113       return -99;
7114     }
7115
7116   M (L2FIB_FLUSH_BD, mp);
7117
7118   mp->bd_id = htonl (bd_id);
7119
7120   S (mp);
7121   W (ret);
7122   return ret;
7123 }
7124
7125 static int
7126 api_l2fib_flush_int (vat_main_t * vam)
7127 {
7128   unformat_input_t *i = vam->input;
7129   vl_api_l2fib_flush_int_t *mp;
7130   u32 sw_if_index = ~0;
7131   int ret;
7132
7133   /* Parse args required to build the message */
7134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7135     {
7136       if (unformat (i, "sw_if_index %d", &sw_if_index));
7137       else
7138         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7139       else
7140         break;
7141     }
7142
7143   if (sw_if_index == ~0)
7144     {
7145       errmsg ("missing interface name or sw_if_index");
7146       return -99;
7147     }
7148
7149   M (L2FIB_FLUSH_INT, mp);
7150
7151   mp->sw_if_index = ntohl (sw_if_index);
7152
7153   S (mp);
7154   W (ret);
7155   return ret;
7156 }
7157
7158 static int
7159 api_l2fib_add_del (vat_main_t * vam)
7160 {
7161   unformat_input_t *i = vam->input;
7162   vl_api_l2fib_add_del_t *mp;
7163   f64 timeout;
7164   u8 mac[6] = { 0 };
7165   u8 mac_set = 0;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   u32 sw_if_index = ~0;
7169   u8 sw_if_index_set = 0;
7170   u8 is_add = 1;
7171   u8 static_mac = 0;
7172   u8 filter_mac = 0;
7173   u8 bvi_mac = 0;
7174   int count = 1;
7175   f64 before = 0;
7176   int j;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7182         mac_set = 1;
7183       else if (unformat (i, "bd_id %d", &bd_id))
7184         bd_id_set = 1;
7185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7186         sw_if_index_set = 1;
7187       else if (unformat (i, "sw_if"))
7188         {
7189           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190             {
7191               if (unformat
7192                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7193                 sw_if_index_set = 1;
7194             }
7195           else
7196             break;
7197         }
7198       else if (unformat (i, "static"))
7199         static_mac = 1;
7200       else if (unformat (i, "filter"))
7201         {
7202           filter_mac = 1;
7203           static_mac = 1;
7204         }
7205       else if (unformat (i, "bvi"))
7206         {
7207           bvi_mac = 1;
7208           static_mac = 1;
7209         }
7210       else if (unformat (i, "del"))
7211         is_add = 0;
7212       else if (unformat (i, "count %d", &count))
7213         ;
7214       else
7215         break;
7216     }
7217
7218   if (mac_set == 0)
7219     {
7220       errmsg ("missing mac address");
7221       return -99;
7222     }
7223
7224   if (bd_id_set == 0)
7225     {
7226       errmsg ("missing bridge domain");
7227       return -99;
7228     }
7229
7230   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7231     {
7232       errmsg ("missing interface name or sw_if_index");
7233       return -99;
7234     }
7235
7236   if (count > 1)
7237     {
7238       /* Turn on async mode */
7239       vam->async_mode = 1;
7240       vam->async_errors = 0;
7241       before = vat_time_now (vam);
7242     }
7243
7244   for (j = 0; j < count; j++)
7245     {
7246       M (L2FIB_ADD_DEL, mp);
7247
7248       clib_memcpy (mp->mac, mac, 6);
7249       mp->bd_id = ntohl (bd_id);
7250       mp->is_add = is_add;
7251
7252       if (is_add)
7253         {
7254           mp->sw_if_index = ntohl (sw_if_index);
7255           mp->static_mac = static_mac;
7256           mp->filter_mac = filter_mac;
7257           mp->bvi_mac = bvi_mac;
7258         }
7259       increment_mac_address (mac);
7260       /* send it... */
7261       S (mp);
7262     }
7263
7264   if (count > 1)
7265     {
7266       vl_api_control_ping_t *mp_ping;
7267       f64 after;
7268
7269       /* Shut off async mode */
7270       vam->async_mode = 0;
7271
7272       MPING (CONTROL_PING, mp_ping);
7273       S (mp_ping);
7274
7275       timeout = vat_time_now (vam) + 1.0;
7276       while (vat_time_now (vam) < timeout)
7277         if (vam->result_ready == 1)
7278           goto out;
7279       vam->retval = -99;
7280
7281     out:
7282       if (vam->retval == -99)
7283         errmsg ("timeout");
7284
7285       if (vam->async_errors > 0)
7286         {
7287           errmsg ("%d asynchronous errors", vam->async_errors);
7288           vam->retval = -98;
7289         }
7290       vam->async_errors = 0;
7291       after = vat_time_now (vam);
7292
7293       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7294              count, after - before, count / (after - before));
7295     }
7296   else
7297     {
7298       int ret;
7299
7300       /* Wait for a reply... */
7301       W (ret);
7302       return ret;
7303     }
7304   /* Return the good/bad news */
7305   return (vam->retval);
7306 }
7307
7308 static int
7309 api_bridge_domain_set_mac_age (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_bridge_domain_set_mac_age_t *mp;
7313   u32 bd_id = ~0;
7314   u32 mac_age = 0;
7315   int ret;
7316
7317   /* Parse args required to build the message */
7318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7319     {
7320       if (unformat (i, "bd_id %d", &bd_id));
7321       else if (unformat (i, "mac-age %d", &mac_age));
7322       else
7323         break;
7324     }
7325
7326   if (bd_id == ~0)
7327     {
7328       errmsg ("missing bridge domain");
7329       return -99;
7330     }
7331
7332   if (mac_age > 255)
7333     {
7334       errmsg ("mac age must be less than 256 ");
7335       return -99;
7336     }
7337
7338   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7339
7340   mp->bd_id = htonl (bd_id);
7341   mp->mac_age = (u8) mac_age;
7342
7343   S (mp);
7344   W (ret);
7345   return ret;
7346 }
7347
7348 static int
7349 api_l2_flags (vat_main_t * vam)
7350 {
7351   unformat_input_t *i = vam->input;
7352   vl_api_l2_flags_t *mp;
7353   u32 sw_if_index;
7354   u32 flags = 0;
7355   u8 sw_if_index_set = 0;
7356   u8 is_set = 0;
7357   int ret;
7358
7359   /* Parse args required to build the message */
7360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7361     {
7362       if (unformat (i, "sw_if_index %d", &sw_if_index))
7363         sw_if_index_set = 1;
7364       else if (unformat (i, "sw_if"))
7365         {
7366           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367             {
7368               if (unformat
7369                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7370                 sw_if_index_set = 1;
7371             }
7372           else
7373             break;
7374         }
7375       else if (unformat (i, "learn"))
7376         flags |= L2_LEARN;
7377       else if (unformat (i, "forward"))
7378         flags |= L2_FWD;
7379       else if (unformat (i, "flood"))
7380         flags |= L2_FLOOD;
7381       else if (unformat (i, "uu-flood"))
7382         flags |= L2_UU_FLOOD;
7383       else if (unformat (i, "arp-term"))
7384         flags |= L2_ARP_TERM;
7385       else if (unformat (i, "off"))
7386         is_set = 0;
7387       else if (unformat (i, "disable"))
7388         is_set = 0;
7389       else
7390         break;
7391     }
7392
7393   if (sw_if_index_set == 0)
7394     {
7395       errmsg ("missing interface name or sw_if_index");
7396       return -99;
7397     }
7398
7399   M (L2_FLAGS, mp);
7400
7401   mp->sw_if_index = ntohl (sw_if_index);
7402   mp->feature_bitmap = ntohl (flags);
7403   mp->is_set = is_set;
7404
7405   S (mp);
7406   W (ret);
7407   return ret;
7408 }
7409
7410 static int
7411 api_bridge_flags (vat_main_t * vam)
7412 {
7413   unformat_input_t *i = vam->input;
7414   vl_api_bridge_flags_t *mp;
7415   u32 bd_id;
7416   u8 bd_id_set = 0;
7417   u8 is_set = 1;
7418   u32 flags = 0;
7419   int ret;
7420
7421   /* Parse args required to build the message */
7422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7423     {
7424       if (unformat (i, "bd_id %d", &bd_id))
7425         bd_id_set = 1;
7426       else if (unformat (i, "learn"))
7427         flags |= L2_LEARN;
7428       else if (unformat (i, "forward"))
7429         flags |= L2_FWD;
7430       else if (unformat (i, "flood"))
7431         flags |= L2_FLOOD;
7432       else if (unformat (i, "uu-flood"))
7433         flags |= L2_UU_FLOOD;
7434       else if (unformat (i, "arp-term"))
7435         flags |= L2_ARP_TERM;
7436       else if (unformat (i, "off"))
7437         is_set = 0;
7438       else if (unformat (i, "disable"))
7439         is_set = 0;
7440       else
7441         break;
7442     }
7443
7444   if (bd_id_set == 0)
7445     {
7446       errmsg ("missing bridge domain");
7447       return -99;
7448     }
7449
7450   M (BRIDGE_FLAGS, mp);
7451
7452   mp->bd_id = ntohl (bd_id);
7453   mp->feature_bitmap = ntohl (flags);
7454   mp->is_set = is_set;
7455
7456   S (mp);
7457   W (ret);
7458   return ret;
7459 }
7460
7461 static int
7462 api_bd_ip_mac_add_del (vat_main_t * vam)
7463 {
7464   unformat_input_t *i = vam->input;
7465   vl_api_bd_ip_mac_add_del_t *mp;
7466   u32 bd_id;
7467   u8 is_ipv6 = 0;
7468   u8 is_add = 1;
7469   u8 bd_id_set = 0;
7470   u8 ip_set = 0;
7471   u8 mac_set = 0;
7472   ip4_address_t v4addr;
7473   ip6_address_t v6addr;
7474   u8 macaddr[6];
7475   int ret;
7476
7477
7478   /* Parse args required to build the message */
7479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7480     {
7481       if (unformat (i, "bd_id %d", &bd_id))
7482         {
7483           bd_id_set++;
7484         }
7485       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7486         {
7487           ip_set++;
7488         }
7489       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7490         {
7491           ip_set++;
7492           is_ipv6++;
7493         }
7494       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7495         {
7496           mac_set++;
7497         }
7498       else if (unformat (i, "del"))
7499         is_add = 0;
7500       else
7501         break;
7502     }
7503
7504   if (bd_id_set == 0)
7505     {
7506       errmsg ("missing bridge domain");
7507       return -99;
7508     }
7509   else if (ip_set == 0)
7510     {
7511       errmsg ("missing IP address");
7512       return -99;
7513     }
7514   else if (mac_set == 0)
7515     {
7516       errmsg ("missing MAC address");
7517       return -99;
7518     }
7519
7520   M (BD_IP_MAC_ADD_DEL, mp);
7521
7522   mp->bd_id = ntohl (bd_id);
7523   mp->is_ipv6 = is_ipv6;
7524   mp->is_add = is_add;
7525   if (is_ipv6)
7526     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7527   else
7528     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7529   clib_memcpy (mp->mac_address, macaddr, 6);
7530   S (mp);
7531   W (ret);
7532   return ret;
7533 }
7534
7535 static int
7536 api_tap_connect (vat_main_t * vam)
7537 {
7538   unformat_input_t *i = vam->input;
7539   vl_api_tap_connect_t *mp;
7540   u8 mac_address[6];
7541   u8 random_mac = 1;
7542   u8 name_set = 0;
7543   u8 *tap_name;
7544   u8 *tag = 0;
7545   ip4_address_t ip4_address;
7546   u32 ip4_mask_width;
7547   int ip4_address_set = 0;
7548   ip6_address_t ip6_address;
7549   u32 ip6_mask_width;
7550   int ip6_address_set = 0;
7551   int ret;
7552
7553   memset (mac_address, 0, sizeof (mac_address));
7554
7555   /* Parse args required to build the message */
7556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7557     {
7558       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7559         {
7560           random_mac = 0;
7561         }
7562       else if (unformat (i, "random-mac"))
7563         random_mac = 1;
7564       else if (unformat (i, "tapname %s", &tap_name))
7565         name_set = 1;
7566       else if (unformat (i, "tag %s", &tag))
7567         ;
7568       else if (unformat (i, "address %U/%d",
7569                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7570         ip4_address_set = 1;
7571       else if (unformat (i, "address %U/%d",
7572                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7573         ip6_address_set = 1;
7574       else
7575         break;
7576     }
7577
7578   if (name_set == 0)
7579     {
7580       errmsg ("missing tap name");
7581       return -99;
7582     }
7583   if (vec_len (tap_name) > 63)
7584     {
7585       errmsg ("tap name too long");
7586       return -99;
7587     }
7588   vec_add1 (tap_name, 0);
7589
7590   if (vec_len (tag) > 63)
7591     {
7592       errmsg ("tag too long");
7593       return -99;
7594     }
7595
7596   /* Construct the API message */
7597   M (TAP_CONNECT, mp);
7598
7599   mp->use_random_mac = random_mac;
7600   clib_memcpy (mp->mac_address, mac_address, 6);
7601   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7602   if (tag)
7603     clib_memcpy (mp->tag, tag, vec_len (tag));
7604
7605   if (ip4_address_set)
7606     {
7607       mp->ip4_address_set = 1;
7608       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7609       mp->ip4_mask_width = ip4_mask_width;
7610     }
7611   if (ip6_address_set)
7612     {
7613       mp->ip6_address_set = 1;
7614       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7615       mp->ip6_mask_width = ip6_mask_width;
7616     }
7617
7618   vec_free (tap_name);
7619   vec_free (tag);
7620
7621   /* send it... */
7622   S (mp);
7623
7624   /* Wait for a reply... */
7625   W (ret);
7626   return ret;
7627 }
7628
7629 static int
7630 api_tap_modify (vat_main_t * vam)
7631 {
7632   unformat_input_t *i = vam->input;
7633   vl_api_tap_modify_t *mp;
7634   u8 mac_address[6];
7635   u8 random_mac = 1;
7636   u8 name_set = 0;
7637   u8 *tap_name;
7638   u32 sw_if_index = ~0;
7639   u8 sw_if_index_set = 0;
7640   int ret;
7641
7642   memset (mac_address, 0, sizeof (mac_address));
7643
7644   /* Parse args required to build the message */
7645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7646     {
7647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7648         sw_if_index_set = 1;
7649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7650         sw_if_index_set = 1;
7651       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7652         {
7653           random_mac = 0;
7654         }
7655       else if (unformat (i, "random-mac"))
7656         random_mac = 1;
7657       else if (unformat (i, "tapname %s", &tap_name))
7658         name_set = 1;
7659       else
7660         break;
7661     }
7662
7663   if (sw_if_index_set == 0)
7664     {
7665       errmsg ("missing vpp interface name");
7666       return -99;
7667     }
7668   if (name_set == 0)
7669     {
7670       errmsg ("missing tap name");
7671       return -99;
7672     }
7673   if (vec_len (tap_name) > 63)
7674     {
7675       errmsg ("tap name too long");
7676     }
7677   vec_add1 (tap_name, 0);
7678
7679   /* Construct the API message */
7680   M (TAP_MODIFY, mp);
7681
7682   mp->use_random_mac = random_mac;
7683   mp->sw_if_index = ntohl (sw_if_index);
7684   clib_memcpy (mp->mac_address, mac_address, 6);
7685   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7686   vec_free (tap_name);
7687
7688   /* send it... */
7689   S (mp);
7690
7691   /* Wait for a reply... */
7692   W (ret);
7693   return ret;
7694 }
7695
7696 static int
7697 api_tap_delete (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_tap_delete_t *mp;
7701   u32 sw_if_index = ~0;
7702   u8 sw_if_index_set = 0;
7703   int ret;
7704
7705   /* Parse args required to build the message */
7706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7707     {
7708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7709         sw_if_index_set = 1;
7710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7711         sw_if_index_set = 1;
7712       else
7713         break;
7714     }
7715
7716   if (sw_if_index_set == 0)
7717     {
7718       errmsg ("missing vpp interface name");
7719       return -99;
7720     }
7721
7722   /* Construct the API message */
7723   M (TAP_DELETE, mp);
7724
7725   mp->sw_if_index = ntohl (sw_if_index);
7726
7727   /* send it... */
7728   S (mp);
7729
7730   /* Wait for a reply... */
7731   W (ret);
7732   return ret;
7733 }
7734
7735 static int
7736 api_ip_table_add_del (vat_main_t * vam)
7737 {
7738   unformat_input_t *i = vam->input;
7739   vl_api_ip_table_add_del_t *mp;
7740   u32 table_id = ~0;
7741   u8 is_ipv6 = 0;
7742   u8 is_add = 1;
7743   int ret = 0;
7744
7745   /* Parse args required to build the message */
7746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7747     {
7748       if (unformat (i, "ipv6"))
7749         is_ipv6 = 1;
7750       else if (unformat (i, "del"))
7751         is_add = 0;
7752       else if (unformat (i, "add"))
7753         is_add = 1;
7754       else if (unformat (i, "table %d", &table_id))
7755         ;
7756       else
7757         {
7758           clib_warning ("parse error '%U'", format_unformat_error, i);
7759           return -99;
7760         }
7761     }
7762
7763   if (~0 == table_id)
7764     {
7765       errmsg ("missing table-ID");
7766       return -99;
7767     }
7768
7769   /* Construct the API message */
7770   M (IP_TABLE_ADD_DEL, mp);
7771
7772   mp->table_id = ntohl (table_id);
7773   mp->is_ipv6 = is_ipv6;
7774   mp->is_add = is_add;
7775
7776   /* send it... */
7777   S (mp);
7778
7779   /* Wait for a reply... */
7780   W (ret);
7781
7782   return ret;
7783 }
7784
7785 static int
7786 api_ip_add_del_route (vat_main_t * vam)
7787 {
7788   unformat_input_t *i = vam->input;
7789   vl_api_ip_add_del_route_t *mp;
7790   u32 sw_if_index = ~0, vrf_id = 0;
7791   u8 is_ipv6 = 0;
7792   u8 is_local = 0, is_drop = 0;
7793   u8 is_unreach = 0, is_prohibit = 0;
7794   u8 create_vrf_if_needed = 0;
7795   u8 is_add = 1;
7796   u32 next_hop_weight = 1;
7797   u8 is_multipath = 0;
7798   u8 address_set = 0;
7799   u8 address_length_set = 0;
7800   u32 next_hop_table_id = 0;
7801   u32 resolve_attempts = 0;
7802   u32 dst_address_length = 0;
7803   u8 next_hop_set = 0;
7804   ip4_address_t v4_dst_address, v4_next_hop_address;
7805   ip6_address_t v6_dst_address, v6_next_hop_address;
7806   int count = 1;
7807   int j;
7808   f64 before = 0;
7809   u32 random_add_del = 0;
7810   u32 *random_vector = 0;
7811   uword *random_hash;
7812   u32 random_seed = 0xdeaddabe;
7813   u32 classify_table_index = ~0;
7814   u8 is_classify = 0;
7815   u8 resolve_host = 0, resolve_attached = 0;
7816   mpls_label_t *next_hop_out_label_stack = NULL;
7817   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7818   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7819
7820   /* Parse args required to build the message */
7821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7822     {
7823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7824         ;
7825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7826         ;
7827       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7828         {
7829           address_set = 1;
7830           is_ipv6 = 0;
7831         }
7832       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7833         {
7834           address_set = 1;
7835           is_ipv6 = 1;
7836         }
7837       else if (unformat (i, "/%d", &dst_address_length))
7838         {
7839           address_length_set = 1;
7840         }
7841
7842       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7843                                          &v4_next_hop_address))
7844         {
7845           next_hop_set = 1;
7846         }
7847       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7848                                          &v6_next_hop_address))
7849         {
7850           next_hop_set = 1;
7851         }
7852       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7853         ;
7854       else if (unformat (i, "weight %d", &next_hop_weight))
7855         ;
7856       else if (unformat (i, "drop"))
7857         {
7858           is_drop = 1;
7859         }
7860       else if (unformat (i, "null-send-unreach"))
7861         {
7862           is_unreach = 1;
7863         }
7864       else if (unformat (i, "null-send-prohibit"))
7865         {
7866           is_prohibit = 1;
7867         }
7868       else if (unformat (i, "local"))
7869         {
7870           is_local = 1;
7871         }
7872       else if (unformat (i, "classify %d", &classify_table_index))
7873         {
7874           is_classify = 1;
7875         }
7876       else if (unformat (i, "del"))
7877         is_add = 0;
7878       else if (unformat (i, "add"))
7879         is_add = 1;
7880       else if (unformat (i, "resolve-via-host"))
7881         resolve_host = 1;
7882       else if (unformat (i, "resolve-via-attached"))
7883         resolve_attached = 1;
7884       else if (unformat (i, "multipath"))
7885         is_multipath = 1;
7886       else if (unformat (i, "vrf %d", &vrf_id))
7887         ;
7888       else if (unformat (i, "create-vrf"))
7889         create_vrf_if_needed = 1;
7890       else if (unformat (i, "count %d", &count))
7891         ;
7892       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7893         ;
7894       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7895         ;
7896       else if (unformat (i, "out-label %d", &next_hop_out_label))
7897         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7898       else if (unformat (i, "via-label %d", &next_hop_via_label))
7899         ;
7900       else if (unformat (i, "random"))
7901         random_add_del = 1;
7902       else if (unformat (i, "seed %d", &random_seed))
7903         ;
7904       else
7905         {
7906           clib_warning ("parse error '%U'", format_unformat_error, i);
7907           return -99;
7908         }
7909     }
7910
7911   if (!next_hop_set && !is_drop && !is_local &&
7912       !is_classify && !is_unreach && !is_prohibit &&
7913       MPLS_LABEL_INVALID == next_hop_via_label)
7914     {
7915       errmsg
7916         ("next hop / local / drop / unreach / prohibit / classify not set");
7917       return -99;
7918     }
7919
7920   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7921     {
7922       errmsg ("next hop and next-hop via label set");
7923       return -99;
7924     }
7925   if (address_set == 0)
7926     {
7927       errmsg ("missing addresses");
7928       return -99;
7929     }
7930
7931   if (address_length_set == 0)
7932     {
7933       errmsg ("missing address length");
7934       return -99;
7935     }
7936
7937   /* Generate a pile of unique, random routes */
7938   if (random_add_del)
7939     {
7940       u32 this_random_address;
7941       random_hash = hash_create (count, sizeof (uword));
7942
7943       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7944       for (j = 0; j <= count; j++)
7945         {
7946           do
7947             {
7948               this_random_address = random_u32 (&random_seed);
7949               this_random_address =
7950                 clib_host_to_net_u32 (this_random_address);
7951             }
7952           while (hash_get (random_hash, this_random_address));
7953           vec_add1 (random_vector, this_random_address);
7954           hash_set (random_hash, this_random_address, 1);
7955         }
7956       hash_free (random_hash);
7957       v4_dst_address.as_u32 = random_vector[0];
7958     }
7959
7960   if (count > 1)
7961     {
7962       /* Turn on async mode */
7963       vam->async_mode = 1;
7964       vam->async_errors = 0;
7965       before = vat_time_now (vam);
7966     }
7967
7968   for (j = 0; j < count; j++)
7969     {
7970       /* Construct the API message */
7971       M2 (IP_ADD_DEL_ROUTE, mp,
7972           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7973
7974       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7975       mp->table_id = ntohl (vrf_id);
7976       mp->create_vrf_if_needed = create_vrf_if_needed;
7977
7978       mp->is_add = is_add;
7979       mp->is_drop = is_drop;
7980       mp->is_unreach = is_unreach;
7981       mp->is_prohibit = is_prohibit;
7982       mp->is_ipv6 = is_ipv6;
7983       mp->is_local = is_local;
7984       mp->is_classify = is_classify;
7985       mp->is_multipath = is_multipath;
7986       mp->is_resolve_host = resolve_host;
7987       mp->is_resolve_attached = resolve_attached;
7988       mp->next_hop_weight = next_hop_weight;
7989       mp->dst_address_length = dst_address_length;
7990       mp->next_hop_table_id = ntohl (next_hop_table_id);
7991       mp->classify_table_index = ntohl (classify_table_index);
7992       mp->next_hop_via_label = ntohl (next_hop_via_label);
7993       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7994       if (0 != mp->next_hop_n_out_labels)
7995         {
7996           memcpy (mp->next_hop_out_label_stack,
7997                   next_hop_out_label_stack,
7998                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7999           vec_free (next_hop_out_label_stack);
8000         }
8001
8002       if (is_ipv6)
8003         {
8004           clib_memcpy (mp->dst_address, &v6_dst_address,
8005                        sizeof (v6_dst_address));
8006           if (next_hop_set)
8007             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8008                          sizeof (v6_next_hop_address));
8009           increment_v6_address (&v6_dst_address);
8010         }
8011       else
8012         {
8013           clib_memcpy (mp->dst_address, &v4_dst_address,
8014                        sizeof (v4_dst_address));
8015           if (next_hop_set)
8016             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8017                          sizeof (v4_next_hop_address));
8018           if (random_add_del)
8019             v4_dst_address.as_u32 = random_vector[j + 1];
8020           else
8021             increment_v4_address (&v4_dst_address);
8022         }
8023       /* send it... */
8024       S (mp);
8025       /* If we receive SIGTERM, stop now... */
8026       if (vam->do_exit)
8027         break;
8028     }
8029
8030   /* When testing multiple add/del ops, use a control-ping to sync */
8031   if (count > 1)
8032     {
8033       vl_api_control_ping_t *mp_ping;
8034       f64 after;
8035       f64 timeout;
8036
8037       /* Shut off async mode */
8038       vam->async_mode = 0;
8039
8040       MPING (CONTROL_PING, mp_ping);
8041       S (mp_ping);
8042
8043       timeout = vat_time_now (vam) + 1.0;
8044       while (vat_time_now (vam) < timeout)
8045         if (vam->result_ready == 1)
8046           goto out;
8047       vam->retval = -99;
8048
8049     out:
8050       if (vam->retval == -99)
8051         errmsg ("timeout");
8052
8053       if (vam->async_errors > 0)
8054         {
8055           errmsg ("%d asynchronous errors", vam->async_errors);
8056           vam->retval = -98;
8057         }
8058       vam->async_errors = 0;
8059       after = vat_time_now (vam);
8060
8061       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8062       if (j > 0)
8063         count = j;
8064
8065       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8066              count, after - before, count / (after - before));
8067     }
8068   else
8069     {
8070       int ret;
8071
8072       /* Wait for a reply... */
8073       W (ret);
8074       return ret;
8075     }
8076
8077   /* Return the good/bad news */
8078   return (vam->retval);
8079 }
8080
8081 static int
8082 api_ip_mroute_add_del (vat_main_t * vam)
8083 {
8084   unformat_input_t *i = vam->input;
8085   vl_api_ip_mroute_add_del_t *mp;
8086   u32 sw_if_index = ~0, vrf_id = 0;
8087   u8 is_ipv6 = 0;
8088   u8 is_local = 0;
8089   u8 create_vrf_if_needed = 0;
8090   u8 is_add = 1;
8091   u8 address_set = 0;
8092   u32 grp_address_length = 0;
8093   ip4_address_t v4_grp_address, v4_src_address;
8094   ip6_address_t v6_grp_address, v6_src_address;
8095   mfib_itf_flags_t iflags = 0;
8096   mfib_entry_flags_t eflags = 0;
8097   int ret;
8098
8099   /* Parse args required to build the message */
8100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8101     {
8102       if (unformat (i, "sw_if_index %d", &sw_if_index))
8103         ;
8104       else if (unformat (i, "%U %U",
8105                          unformat_ip4_address, &v4_src_address,
8106                          unformat_ip4_address, &v4_grp_address))
8107         {
8108           grp_address_length = 64;
8109           address_set = 1;
8110           is_ipv6 = 0;
8111         }
8112       else if (unformat (i, "%U %U",
8113                          unformat_ip6_address, &v6_src_address,
8114                          unformat_ip6_address, &v6_grp_address))
8115         {
8116           grp_address_length = 256;
8117           address_set = 1;
8118           is_ipv6 = 1;
8119         }
8120       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8121         {
8122           memset (&v4_src_address, 0, sizeof (v4_src_address));
8123           grp_address_length = 32;
8124           address_set = 1;
8125           is_ipv6 = 0;
8126         }
8127       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8128         {
8129           memset (&v6_src_address, 0, sizeof (v6_src_address));
8130           grp_address_length = 128;
8131           address_set = 1;
8132           is_ipv6 = 1;
8133         }
8134       else if (unformat (i, "/%d", &grp_address_length))
8135         ;
8136       else if (unformat (i, "local"))
8137         {
8138           is_local = 1;
8139         }
8140       else if (unformat (i, "del"))
8141         is_add = 0;
8142       else if (unformat (i, "add"))
8143         is_add = 1;
8144       else if (unformat (i, "vrf %d", &vrf_id))
8145         ;
8146       else if (unformat (i, "create-vrf"))
8147         create_vrf_if_needed = 1;
8148       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8149         ;
8150       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8151         ;
8152       else
8153         {
8154           clib_warning ("parse error '%U'", format_unformat_error, i);
8155           return -99;
8156         }
8157     }
8158
8159   if (address_set == 0)
8160     {
8161       errmsg ("missing addresses\n");
8162       return -99;
8163     }
8164
8165   /* Construct the API message */
8166   M (IP_MROUTE_ADD_DEL, mp);
8167
8168   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8169   mp->table_id = ntohl (vrf_id);
8170   mp->create_vrf_if_needed = create_vrf_if_needed;
8171
8172   mp->is_add = is_add;
8173   mp->is_ipv6 = is_ipv6;
8174   mp->is_local = is_local;
8175   mp->itf_flags = ntohl (iflags);
8176   mp->entry_flags = ntohl (eflags);
8177   mp->grp_address_length = grp_address_length;
8178   mp->grp_address_length = ntohs (mp->grp_address_length);
8179
8180   if (is_ipv6)
8181     {
8182       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8183       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8184     }
8185   else
8186     {
8187       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8188       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8189
8190     }
8191
8192   /* send it... */
8193   S (mp);
8194   /* Wait for a reply... */
8195   W (ret);
8196   return ret;
8197 }
8198
8199 static int
8200 api_mpls_table_add_del (vat_main_t * vam)
8201 {
8202   unformat_input_t *i = vam->input;
8203   vl_api_mpls_table_add_del_t *mp;
8204   u32 table_id = ~0;
8205   u8 is_add = 1;
8206   int ret = 0;
8207
8208   /* Parse args required to build the message */
8209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8210     {
8211       if (unformat (i, "table %d", &table_id))
8212         ;
8213       else if (unformat (i, "del"))
8214         is_add = 0;
8215       else if (unformat (i, "add"))
8216         is_add = 1;
8217       else
8218         {
8219           clib_warning ("parse error '%U'", format_unformat_error, i);
8220           return -99;
8221         }
8222     }
8223
8224   if (~0 == table_id)
8225     {
8226       errmsg ("missing table-ID");
8227       return -99;
8228     }
8229
8230   /* Construct the API message */
8231   M (MPLS_TABLE_ADD_DEL, mp);
8232
8233   mp->mt_table_id = ntohl (table_id);
8234   mp->mt_is_add = is_add;
8235
8236   /* send it... */
8237   S (mp);
8238
8239   /* Wait for a reply... */
8240   W (ret);
8241
8242   return ret;
8243 }
8244
8245 static int
8246 api_mpls_route_add_del (vat_main_t * vam)
8247 {
8248   unformat_input_t *i = vam->input;
8249   vl_api_mpls_route_add_del_t *mp;
8250   u32 sw_if_index = ~0, table_id = 0;
8251   u8 create_table_if_needed = 0;
8252   u8 is_add = 1;
8253   u32 next_hop_weight = 1;
8254   u8 is_multipath = 0;
8255   u32 next_hop_table_id = 0;
8256   u8 next_hop_set = 0;
8257   ip4_address_t v4_next_hop_address = {
8258     .as_u32 = 0,
8259   };
8260   ip6_address_t v6_next_hop_address = { {0} };
8261   int count = 1;
8262   int j;
8263   f64 before = 0;
8264   u32 classify_table_index = ~0;
8265   u8 is_classify = 0;
8266   u8 resolve_host = 0, resolve_attached = 0;
8267   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8268   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8269   mpls_label_t *next_hop_out_label_stack = NULL;
8270   mpls_label_t local_label = MPLS_LABEL_INVALID;
8271   u8 is_eos = 0;
8272   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8273
8274   /* Parse args required to build the message */
8275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8276     {
8277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8278         ;
8279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8280         ;
8281       else if (unformat (i, "%d", &local_label))
8282         ;
8283       else if (unformat (i, "eos"))
8284         is_eos = 1;
8285       else if (unformat (i, "non-eos"))
8286         is_eos = 0;
8287       else if (unformat (i, "via %U", unformat_ip4_address,
8288                          &v4_next_hop_address))
8289         {
8290           next_hop_set = 1;
8291           next_hop_proto = DPO_PROTO_IP4;
8292         }
8293       else if (unformat (i, "via %U", unformat_ip6_address,
8294                          &v6_next_hop_address))
8295         {
8296           next_hop_set = 1;
8297           next_hop_proto = DPO_PROTO_IP6;
8298         }
8299       else if (unformat (i, "weight %d", &next_hop_weight))
8300         ;
8301       else if (unformat (i, "create-table"))
8302         create_table_if_needed = 1;
8303       else if (unformat (i, "classify %d", &classify_table_index))
8304         {
8305           is_classify = 1;
8306         }
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else if (unformat (i, "add"))
8310         is_add = 1;
8311       else if (unformat (i, "resolve-via-host"))
8312         resolve_host = 1;
8313       else if (unformat (i, "resolve-via-attached"))
8314         resolve_attached = 1;
8315       else if (unformat (i, "multipath"))
8316         is_multipath = 1;
8317       else if (unformat (i, "count %d", &count))
8318         ;
8319       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8320         {
8321           next_hop_set = 1;
8322           next_hop_proto = DPO_PROTO_IP4;
8323         }
8324       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8325         {
8326           next_hop_set = 1;
8327           next_hop_proto = DPO_PROTO_IP6;
8328         }
8329       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8330         ;
8331       else if (unformat (i, "via-label %d", &next_hop_via_label))
8332         ;
8333       else if (unformat (i, "out-label %d", &next_hop_out_label))
8334         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8335       else
8336         {
8337           clib_warning ("parse error '%U'", format_unformat_error, i);
8338           return -99;
8339         }
8340     }
8341
8342   if (!next_hop_set && !is_classify)
8343     {
8344       errmsg ("next hop / classify not set");
8345       return -99;
8346     }
8347
8348   if (MPLS_LABEL_INVALID == local_label)
8349     {
8350       errmsg ("missing label");
8351       return -99;
8352     }
8353
8354   if (count > 1)
8355     {
8356       /* Turn on async mode */
8357       vam->async_mode = 1;
8358       vam->async_errors = 0;
8359       before = vat_time_now (vam);
8360     }
8361
8362   for (j = 0; j < count; j++)
8363     {
8364       /* Construct the API message */
8365       M2 (MPLS_ROUTE_ADD_DEL, mp,
8366           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8367
8368       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8369       mp->mr_table_id = ntohl (table_id);
8370       mp->mr_create_table_if_needed = create_table_if_needed;
8371
8372       mp->mr_is_add = is_add;
8373       mp->mr_next_hop_proto = next_hop_proto;
8374       mp->mr_is_classify = is_classify;
8375       mp->mr_is_multipath = is_multipath;
8376       mp->mr_is_resolve_host = resolve_host;
8377       mp->mr_is_resolve_attached = resolve_attached;
8378       mp->mr_next_hop_weight = next_hop_weight;
8379       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8380       mp->mr_classify_table_index = ntohl (classify_table_index);
8381       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8382       mp->mr_label = ntohl (local_label);
8383       mp->mr_eos = is_eos;
8384
8385       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8386       if (0 != mp->mr_next_hop_n_out_labels)
8387         {
8388           memcpy (mp->mr_next_hop_out_label_stack,
8389                   next_hop_out_label_stack,
8390                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8391           vec_free (next_hop_out_label_stack);
8392         }
8393
8394       if (next_hop_set)
8395         {
8396           if (DPO_PROTO_IP4 == next_hop_proto)
8397             {
8398               clib_memcpy (mp->mr_next_hop,
8399                            &v4_next_hop_address,
8400                            sizeof (v4_next_hop_address));
8401             }
8402           else if (DPO_PROTO_IP6 == next_hop_proto)
8403
8404             {
8405               clib_memcpy (mp->mr_next_hop,
8406                            &v6_next_hop_address,
8407                            sizeof (v6_next_hop_address));
8408             }
8409         }
8410       local_label++;
8411
8412       /* send it... */
8413       S (mp);
8414       /* If we receive SIGTERM, stop now... */
8415       if (vam->do_exit)
8416         break;
8417     }
8418
8419   /* When testing multiple add/del ops, use a control-ping to sync */
8420   if (count > 1)
8421     {
8422       vl_api_control_ping_t *mp_ping;
8423       f64 after;
8424       f64 timeout;
8425
8426       /* Shut off async mode */
8427       vam->async_mode = 0;
8428
8429       MPING (CONTROL_PING, mp_ping);
8430       S (mp_ping);
8431
8432       timeout = vat_time_now (vam) + 1.0;
8433       while (vat_time_now (vam) < timeout)
8434         if (vam->result_ready == 1)
8435           goto out;
8436       vam->retval = -99;
8437
8438     out:
8439       if (vam->retval == -99)
8440         errmsg ("timeout");
8441
8442       if (vam->async_errors > 0)
8443         {
8444           errmsg ("%d asynchronous errors", vam->async_errors);
8445           vam->retval = -98;
8446         }
8447       vam->async_errors = 0;
8448       after = vat_time_now (vam);
8449
8450       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8451       if (j > 0)
8452         count = j;
8453
8454       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8455              count, after - before, count / (after - before));
8456     }
8457   else
8458     {
8459       int ret;
8460
8461       /* Wait for a reply... */
8462       W (ret);
8463       return ret;
8464     }
8465
8466   /* Return the good/bad news */
8467   return (vam->retval);
8468 }
8469
8470 static int
8471 api_mpls_ip_bind_unbind (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_mpls_ip_bind_unbind_t *mp;
8475   u32 ip_table_id = 0;
8476   u8 create_table_if_needed = 0;
8477   u8 is_bind = 1;
8478   u8 is_ip4 = 1;
8479   ip4_address_t v4_address;
8480   ip6_address_t v6_address;
8481   u32 address_length;
8482   u8 address_set = 0;
8483   mpls_label_t local_label = MPLS_LABEL_INVALID;
8484   int ret;
8485
8486   /* Parse args required to build the message */
8487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (i, "%U/%d", unformat_ip4_address,
8490                     &v4_address, &address_length))
8491         {
8492           is_ip4 = 1;
8493           address_set = 1;
8494         }
8495       else if (unformat (i, "%U/%d", unformat_ip6_address,
8496                          &v6_address, &address_length))
8497         {
8498           is_ip4 = 0;
8499           address_set = 1;
8500         }
8501       else if (unformat (i, "%d", &local_label))
8502         ;
8503       else if (unformat (i, "create-table"))
8504         create_table_if_needed = 1;
8505       else if (unformat (i, "table-id %d", &ip_table_id))
8506         ;
8507       else if (unformat (i, "unbind"))
8508         is_bind = 0;
8509       else if (unformat (i, "bind"))
8510         is_bind = 1;
8511       else
8512         {
8513           clib_warning ("parse error '%U'", format_unformat_error, i);
8514           return -99;
8515         }
8516     }
8517
8518   if (!address_set)
8519     {
8520       errmsg ("IP addres not set");
8521       return -99;
8522     }
8523
8524   if (MPLS_LABEL_INVALID == local_label)
8525     {
8526       errmsg ("missing label");
8527       return -99;
8528     }
8529
8530   /* Construct the API message */
8531   M (MPLS_IP_BIND_UNBIND, mp);
8532
8533   mp->mb_create_table_if_needed = create_table_if_needed;
8534   mp->mb_is_bind = is_bind;
8535   mp->mb_is_ip4 = is_ip4;
8536   mp->mb_ip_table_id = ntohl (ip_table_id);
8537   mp->mb_mpls_table_id = 0;
8538   mp->mb_label = ntohl (local_label);
8539   mp->mb_address_length = address_length;
8540
8541   if (is_ip4)
8542     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8543   else
8544     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8545
8546   /* send it... */
8547   S (mp);
8548
8549   /* Wait for a reply... */
8550   W (ret);
8551   return ret;
8552 }
8553
8554 static int
8555 api_bier_table_add_del (vat_main_t * vam)
8556 {
8557   unformat_input_t *i = vam->input;
8558   vl_api_bier_table_add_del_t *mp;
8559   u8 is_add = 1;
8560   u32 set = 0, sub_domain = 0, hdr_len = 3;
8561   mpls_label_t local_label = MPLS_LABEL_INVALID;
8562   int ret;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "sub-domain %d", &sub_domain))
8568         ;
8569       else if (unformat (i, "set %d", &set))
8570         ;
8571       else if (unformat (i, "label %d", &local_label))
8572         ;
8573       else if (unformat (i, "hdr-len %d", &hdr_len))
8574         ;
8575       else if (unformat (i, "add"))
8576         is_add = 1;
8577       else if (unformat (i, "del"))
8578         is_add = 0;
8579       else
8580         {
8581           clib_warning ("parse error '%U'", format_unformat_error, i);
8582           return -99;
8583         }
8584     }
8585
8586   if (MPLS_LABEL_INVALID == local_label)
8587     {
8588       errmsg ("missing label\n");
8589       return -99;
8590     }
8591
8592   /* Construct the API message */
8593   M (BIER_TABLE_ADD_DEL, mp);
8594
8595   mp->bt_is_add = is_add;
8596   mp->bt_label = ntohl (local_label);
8597   mp->bt_tbl_id.bt_set = set;
8598   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8599   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8600
8601   /* send it... */
8602   S (mp);
8603
8604   /* Wait for a reply... */
8605   W (ret);
8606
8607   return (ret);
8608 }
8609
8610 static int
8611 api_bier_route_add_del (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_bier_route_add_del_t *mp;
8615   u8 is_add = 1;
8616   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8617   ip4_address_t v4_next_hop_address;
8618   ip6_address_t v6_next_hop_address;
8619   u8 next_hop_set = 0;
8620   u8 next_hop_proto_is_ip4 = 1;
8621   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8622   int ret;
8623
8624   /* Parse args required to build the message */
8625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8626     {
8627       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8628         {
8629           next_hop_proto_is_ip4 = 1;
8630           next_hop_set = 1;
8631         }
8632       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8633         {
8634           next_hop_proto_is_ip4 = 0;
8635           next_hop_set = 1;
8636         }
8637       if (unformat (i, "sub-domain %d", &sub_domain))
8638         ;
8639       else if (unformat (i, "set %d", &set))
8640         ;
8641       else if (unformat (i, "hdr-len %d", &hdr_len))
8642         ;
8643       else if (unformat (i, "bp %d", &bp))
8644         ;
8645       else if (unformat (i, "add"))
8646         is_add = 1;
8647       else if (unformat (i, "del"))
8648         is_add = 0;
8649       else if (unformat (i, "out-label %d", &next_hop_out_label))
8650         ;
8651       else
8652         {
8653           clib_warning ("parse error '%U'", format_unformat_error, i);
8654           return -99;
8655         }
8656     }
8657
8658   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8659     {
8660       errmsg ("next hop / label set\n");
8661       return -99;
8662     }
8663   if (0 == bp)
8664     {
8665       errmsg ("bit=position not set\n");
8666       return -99;
8667     }
8668
8669   /* Construct the API message */
8670   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8671
8672   mp->br_is_add = is_add;
8673   mp->br_tbl_id.bt_set = set;
8674   mp->br_tbl_id.bt_sub_domain = sub_domain;
8675   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8676   mp->br_bp = ntohs (bp);
8677   mp->br_n_paths = 1;
8678   mp->br_paths[0].n_labels = 1;
8679   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8680   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8681
8682   if (next_hop_proto_is_ip4)
8683     {
8684       clib_memcpy (mp->br_paths[0].next_hop,
8685                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8686     }
8687   else
8688     {
8689       clib_memcpy (mp->br_paths[0].next_hop,
8690                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8691     }
8692
8693   /* send it... */
8694   S (mp);
8695
8696   /* Wait for a reply... */
8697   W (ret);
8698
8699   return (ret);
8700 }
8701
8702 static int
8703 api_proxy_arp_add_del (vat_main_t * vam)
8704 {
8705   unformat_input_t *i = vam->input;
8706   vl_api_proxy_arp_add_del_t *mp;
8707   u32 vrf_id = 0;
8708   u8 is_add = 1;
8709   ip4_address_t lo, hi;
8710   u8 range_set = 0;
8711   int ret;
8712
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "vrf %d", &vrf_id))
8716         ;
8717       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8718                          unformat_ip4_address, &hi))
8719         range_set = 1;
8720       else if (unformat (i, "del"))
8721         is_add = 0;
8722       else
8723         {
8724           clib_warning ("parse error '%U'", format_unformat_error, i);
8725           return -99;
8726         }
8727     }
8728
8729   if (range_set == 0)
8730     {
8731       errmsg ("address range not set");
8732       return -99;
8733     }
8734
8735   M (PROXY_ARP_ADD_DEL, mp);
8736
8737   mp->vrf_id = ntohl (vrf_id);
8738   mp->is_add = is_add;
8739   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8740   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8741
8742   S (mp);
8743   W (ret);
8744   return ret;
8745 }
8746
8747 static int
8748 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8749 {
8750   unformat_input_t *i = vam->input;
8751   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8752   u32 sw_if_index;
8753   u8 enable = 1;
8754   u8 sw_if_index_set = 0;
8755   int ret;
8756
8757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8758     {
8759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8760         sw_if_index_set = 1;
8761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8762         sw_if_index_set = 1;
8763       else if (unformat (i, "enable"))
8764         enable = 1;
8765       else if (unformat (i, "disable"))
8766         enable = 0;
8767       else
8768         {
8769           clib_warning ("parse error '%U'", format_unformat_error, i);
8770           return -99;
8771         }
8772     }
8773
8774   if (sw_if_index_set == 0)
8775     {
8776       errmsg ("missing interface name or sw_if_index");
8777       return -99;
8778     }
8779
8780   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8781
8782   mp->sw_if_index = ntohl (sw_if_index);
8783   mp->enable_disable = enable;
8784
8785   S (mp);
8786   W (ret);
8787   return ret;
8788 }
8789
8790 static int
8791 api_mpls_tunnel_add_del (vat_main_t * vam)
8792 {
8793   unformat_input_t *i = vam->input;
8794   vl_api_mpls_tunnel_add_del_t *mp;
8795
8796   u8 is_add = 1;
8797   u8 l2_only = 0;
8798   u32 sw_if_index = ~0;
8799   u32 next_hop_sw_if_index = ~0;
8800   u32 next_hop_proto_is_ip4 = 1;
8801
8802   u32 next_hop_table_id = 0;
8803   ip4_address_t v4_next_hop_address = {
8804     .as_u32 = 0,
8805   };
8806   ip6_address_t v6_next_hop_address = { {0} };
8807   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8808   int ret;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "add"))
8813         is_add = 1;
8814       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8815         is_add = 0;
8816       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8817         ;
8818       else if (unformat (i, "via %U",
8819                          unformat_ip4_address, &v4_next_hop_address))
8820         {
8821           next_hop_proto_is_ip4 = 1;
8822         }
8823       else if (unformat (i, "via %U",
8824                          unformat_ip6_address, &v6_next_hop_address))
8825         {
8826           next_hop_proto_is_ip4 = 0;
8827         }
8828       else if (unformat (i, "l2-only"))
8829         l2_only = 1;
8830       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8831         ;
8832       else if (unformat (i, "out-label %d", &next_hop_out_label))
8833         vec_add1 (labels, ntohl (next_hop_out_label));
8834       else
8835         {
8836           clib_warning ("parse error '%U'", format_unformat_error, i);
8837           return -99;
8838         }
8839     }
8840
8841   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8842
8843   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8844   mp->mt_sw_if_index = ntohl (sw_if_index);
8845   mp->mt_is_add = is_add;
8846   mp->mt_l2_only = l2_only;
8847   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8848   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8849
8850   mp->mt_next_hop_n_out_labels = vec_len (labels);
8851
8852   if (0 != mp->mt_next_hop_n_out_labels)
8853     {
8854       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8855                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8856       vec_free (labels);
8857     }
8858
8859   if (next_hop_proto_is_ip4)
8860     {
8861       clib_memcpy (mp->mt_next_hop,
8862                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8863     }
8864   else
8865     {
8866       clib_memcpy (mp->mt_next_hop,
8867                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8868     }
8869
8870   S (mp);
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_sw_interface_set_unnumbered (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_sw_interface_set_unnumbered_t *mp;
8880   u32 sw_if_index;
8881   u32 unnum_sw_index = ~0;
8882   u8 is_add = 1;
8883   u8 sw_if_index_set = 0;
8884   int ret;
8885
8886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8887     {
8888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8889         sw_if_index_set = 1;
8890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8891         sw_if_index_set = 1;
8892       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8893         ;
8894       else if (unformat (i, "del"))
8895         is_add = 0;
8896       else
8897         {
8898           clib_warning ("parse error '%U'", format_unformat_error, i);
8899           return -99;
8900         }
8901     }
8902
8903   if (sw_if_index_set == 0)
8904     {
8905       errmsg ("missing interface name or sw_if_index");
8906       return -99;
8907     }
8908
8909   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8910
8911   mp->sw_if_index = ntohl (sw_if_index);
8912   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8913   mp->is_add = is_add;
8914
8915   S (mp);
8916   W (ret);
8917   return ret;
8918 }
8919
8920 static int
8921 api_ip_neighbor_add_del (vat_main_t * vam)
8922 {
8923   unformat_input_t *i = vam->input;
8924   vl_api_ip_neighbor_add_del_t *mp;
8925   u32 sw_if_index;
8926   u8 sw_if_index_set = 0;
8927   u8 is_add = 1;
8928   u8 is_static = 0;
8929   u8 is_no_fib_entry = 0;
8930   u8 mac_address[6];
8931   u8 mac_set = 0;
8932   u8 v4_address_set = 0;
8933   u8 v6_address_set = 0;
8934   ip4_address_t v4address;
8935   ip6_address_t v6address;
8936   int ret;
8937
8938   memset (mac_address, 0, sizeof (mac_address));
8939
8940   /* Parse args required to build the message */
8941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8942     {
8943       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8944         {
8945           mac_set = 1;
8946         }
8947       else if (unformat (i, "del"))
8948         is_add = 0;
8949       else
8950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8951         sw_if_index_set = 1;
8952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8953         sw_if_index_set = 1;
8954       else if (unformat (i, "is_static"))
8955         is_static = 1;
8956       else if (unformat (i, "no-fib-entry"))
8957         is_no_fib_entry = 1;
8958       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8959         v4_address_set = 1;
8960       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8961         v6_address_set = 1;
8962       else
8963         {
8964           clib_warning ("parse error '%U'", format_unformat_error, i);
8965           return -99;
8966         }
8967     }
8968
8969   if (sw_if_index_set == 0)
8970     {
8971       errmsg ("missing interface name or sw_if_index");
8972       return -99;
8973     }
8974   if (v4_address_set && v6_address_set)
8975     {
8976       errmsg ("both v4 and v6 addresses set");
8977       return -99;
8978     }
8979   if (!v4_address_set && !v6_address_set)
8980     {
8981       errmsg ("no address set");
8982       return -99;
8983     }
8984
8985   /* Construct the API message */
8986   M (IP_NEIGHBOR_ADD_DEL, mp);
8987
8988   mp->sw_if_index = ntohl (sw_if_index);
8989   mp->is_add = is_add;
8990   mp->is_static = is_static;
8991   mp->is_no_adj_fib = is_no_fib_entry;
8992   if (mac_set)
8993     clib_memcpy (mp->mac_address, mac_address, 6);
8994   if (v6_address_set)
8995     {
8996       mp->is_ipv6 = 1;
8997       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8998     }
8999   else
9000     {
9001       /* mp->is_ipv6 = 0; via memset in M macro above */
9002       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9003     }
9004
9005   /* send it... */
9006   S (mp);
9007
9008   /* Wait for a reply, return good/bad news  */
9009   W (ret);
9010   return ret;
9011 }
9012
9013 static int
9014 api_reset_vrf (vat_main_t * vam)
9015 {
9016   unformat_input_t *i = vam->input;
9017   vl_api_reset_vrf_t *mp;
9018   u32 vrf_id = 0;
9019   u8 is_ipv6 = 0;
9020   u8 vrf_id_set = 0;
9021   int ret;
9022
9023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9024     {
9025       if (unformat (i, "vrf %d", &vrf_id))
9026         vrf_id_set = 1;
9027       else if (unformat (i, "ipv6"))
9028         is_ipv6 = 1;
9029       else
9030         {
9031           clib_warning ("parse error '%U'", format_unformat_error, i);
9032           return -99;
9033         }
9034     }
9035
9036   if (vrf_id_set == 0)
9037     {
9038       errmsg ("missing vrf id");
9039       return -99;
9040     }
9041
9042   M (RESET_VRF, mp);
9043
9044   mp->vrf_id = ntohl (vrf_id);
9045   mp->is_ipv6 = is_ipv6;
9046
9047   S (mp);
9048   W (ret);
9049   return ret;
9050 }
9051
9052 static int
9053 api_create_vlan_subif (vat_main_t * vam)
9054 {
9055   unformat_input_t *i = vam->input;
9056   vl_api_create_vlan_subif_t *mp;
9057   u32 sw_if_index;
9058   u8 sw_if_index_set = 0;
9059   u32 vlan_id;
9060   u8 vlan_id_set = 0;
9061   int ret;
9062
9063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064     {
9065       if (unformat (i, "sw_if_index %d", &sw_if_index))
9066         sw_if_index_set = 1;
9067       else
9068         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9069         sw_if_index_set = 1;
9070       else if (unformat (i, "vlan %d", &vlan_id))
9071         vlan_id_set = 1;
9072       else
9073         {
9074           clib_warning ("parse error '%U'", format_unformat_error, i);
9075           return -99;
9076         }
9077     }
9078
9079   if (sw_if_index_set == 0)
9080     {
9081       errmsg ("missing interface name or sw_if_index");
9082       return -99;
9083     }
9084
9085   if (vlan_id_set == 0)
9086     {
9087       errmsg ("missing vlan_id");
9088       return -99;
9089     }
9090   M (CREATE_VLAN_SUBIF, mp);
9091
9092   mp->sw_if_index = ntohl (sw_if_index);
9093   mp->vlan_id = ntohl (vlan_id);
9094
9095   S (mp);
9096   W (ret);
9097   return ret;
9098 }
9099
9100 #define foreach_create_subif_bit                \
9101 _(no_tags)                                      \
9102 _(one_tag)                                      \
9103 _(two_tags)                                     \
9104 _(dot1ad)                                       \
9105 _(exact_match)                                  \
9106 _(default_sub)                                  \
9107 _(outer_vlan_id_any)                            \
9108 _(inner_vlan_id_any)
9109
9110 static int
9111 api_create_subif (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_create_subif_t *mp;
9115   u32 sw_if_index;
9116   u8 sw_if_index_set = 0;
9117   u32 sub_id;
9118   u8 sub_id_set = 0;
9119   u32 no_tags = 0;
9120   u32 one_tag = 0;
9121   u32 two_tags = 0;
9122   u32 dot1ad = 0;
9123   u32 exact_match = 0;
9124   u32 default_sub = 0;
9125   u32 outer_vlan_id_any = 0;
9126   u32 inner_vlan_id_any = 0;
9127   u32 tmp;
9128   u16 outer_vlan_id = 0;
9129   u16 inner_vlan_id = 0;
9130   int ret;
9131
9132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9133     {
9134       if (unformat (i, "sw_if_index %d", &sw_if_index))
9135         sw_if_index_set = 1;
9136       else
9137         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9138         sw_if_index_set = 1;
9139       else if (unformat (i, "sub_id %d", &sub_id))
9140         sub_id_set = 1;
9141       else if (unformat (i, "outer_vlan_id %d", &tmp))
9142         outer_vlan_id = tmp;
9143       else if (unformat (i, "inner_vlan_id %d", &tmp))
9144         inner_vlan_id = tmp;
9145
9146 #define _(a) else if (unformat (i, #a)) a = 1 ;
9147       foreach_create_subif_bit
9148 #undef _
9149         else
9150         {
9151           clib_warning ("parse error '%U'", format_unformat_error, i);
9152           return -99;
9153         }
9154     }
9155
9156   if (sw_if_index_set == 0)
9157     {
9158       errmsg ("missing interface name or sw_if_index");
9159       return -99;
9160     }
9161
9162   if (sub_id_set == 0)
9163     {
9164       errmsg ("missing sub_id");
9165       return -99;
9166     }
9167   M (CREATE_SUBIF, mp);
9168
9169   mp->sw_if_index = ntohl (sw_if_index);
9170   mp->sub_id = ntohl (sub_id);
9171
9172 #define _(a) mp->a = a;
9173   foreach_create_subif_bit;
9174 #undef _
9175
9176   mp->outer_vlan_id = ntohs (outer_vlan_id);
9177   mp->inner_vlan_id = ntohs (inner_vlan_id);
9178
9179   S (mp);
9180   W (ret);
9181   return ret;
9182 }
9183
9184 static int
9185 api_oam_add_del (vat_main_t * vam)
9186 {
9187   unformat_input_t *i = vam->input;
9188   vl_api_oam_add_del_t *mp;
9189   u32 vrf_id = 0;
9190   u8 is_add = 1;
9191   ip4_address_t src, dst;
9192   u8 src_set = 0;
9193   u8 dst_set = 0;
9194   int ret;
9195
9196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (i, "vrf %d", &vrf_id))
9199         ;
9200       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9201         src_set = 1;
9202       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9203         dst_set = 1;
9204       else if (unformat (i, "del"))
9205         is_add = 0;
9206       else
9207         {
9208           clib_warning ("parse error '%U'", format_unformat_error, i);
9209           return -99;
9210         }
9211     }
9212
9213   if (src_set == 0)
9214     {
9215       errmsg ("missing src addr");
9216       return -99;
9217     }
9218
9219   if (dst_set == 0)
9220     {
9221       errmsg ("missing dst addr");
9222       return -99;
9223     }
9224
9225   M (OAM_ADD_DEL, mp);
9226
9227   mp->vrf_id = ntohl (vrf_id);
9228   mp->is_add = is_add;
9229   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9230   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9231
9232   S (mp);
9233   W (ret);
9234   return ret;
9235 }
9236
9237 static int
9238 api_reset_fib (vat_main_t * vam)
9239 {
9240   unformat_input_t *i = vam->input;
9241   vl_api_reset_fib_t *mp;
9242   u32 vrf_id = 0;
9243   u8 is_ipv6 = 0;
9244   u8 vrf_id_set = 0;
9245
9246   int ret;
9247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9248     {
9249       if (unformat (i, "vrf %d", &vrf_id))
9250         vrf_id_set = 1;
9251       else if (unformat (i, "ipv6"))
9252         is_ipv6 = 1;
9253       else
9254         {
9255           clib_warning ("parse error '%U'", format_unformat_error, i);
9256           return -99;
9257         }
9258     }
9259
9260   if (vrf_id_set == 0)
9261     {
9262       errmsg ("missing vrf id");
9263       return -99;
9264     }
9265
9266   M (RESET_FIB, mp);
9267
9268   mp->vrf_id = ntohl (vrf_id);
9269   mp->is_ipv6 = is_ipv6;
9270
9271   S (mp);
9272   W (ret);
9273   return ret;
9274 }
9275
9276 static int
9277 api_dhcp_proxy_config (vat_main_t * vam)
9278 {
9279   unformat_input_t *i = vam->input;
9280   vl_api_dhcp_proxy_config_t *mp;
9281   u32 rx_vrf_id = 0;
9282   u32 server_vrf_id = 0;
9283   u8 is_add = 1;
9284   u8 v4_address_set = 0;
9285   u8 v6_address_set = 0;
9286   ip4_address_t v4address;
9287   ip6_address_t v6address;
9288   u8 v4_src_address_set = 0;
9289   u8 v6_src_address_set = 0;
9290   ip4_address_t v4srcaddress;
9291   ip6_address_t v6srcaddress;
9292   int ret;
9293
9294   /* Parse args required to build the message */
9295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9296     {
9297       if (unformat (i, "del"))
9298         is_add = 0;
9299       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9300         ;
9301       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9302         ;
9303       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9304         v4_address_set = 1;
9305       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9306         v6_address_set = 1;
9307       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9308         v4_src_address_set = 1;
9309       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9310         v6_src_address_set = 1;
9311       else
9312         break;
9313     }
9314
9315   if (v4_address_set && v6_address_set)
9316     {
9317       errmsg ("both v4 and v6 server addresses set");
9318       return -99;
9319     }
9320   if (!v4_address_set && !v6_address_set)
9321     {
9322       errmsg ("no server addresses set");
9323       return -99;
9324     }
9325
9326   if (v4_src_address_set && v6_src_address_set)
9327     {
9328       errmsg ("both v4 and v6  src addresses set");
9329       return -99;
9330     }
9331   if (!v4_src_address_set && !v6_src_address_set)
9332     {
9333       errmsg ("no src addresses set");
9334       return -99;
9335     }
9336
9337   if (!(v4_src_address_set && v4_address_set) &&
9338       !(v6_src_address_set && v6_address_set))
9339     {
9340       errmsg ("no matching server and src addresses set");
9341       return -99;
9342     }
9343
9344   /* Construct the API message */
9345   M (DHCP_PROXY_CONFIG, mp);
9346
9347   mp->is_add = is_add;
9348   mp->rx_vrf_id = ntohl (rx_vrf_id);
9349   mp->server_vrf_id = ntohl (server_vrf_id);
9350   if (v6_address_set)
9351     {
9352       mp->is_ipv6 = 1;
9353       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9354       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9355     }
9356   else
9357     {
9358       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9359       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9360     }
9361
9362   /* send it... */
9363   S (mp);
9364
9365   /* Wait for a reply, return good/bad news  */
9366   W (ret);
9367   return ret;
9368 }
9369
9370 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9371 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9372
9373 static void
9374 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9375 {
9376   vat_main_t *vam = &vat_main;
9377   u32 i, count = mp->count;
9378   vl_api_dhcp_server_t *s;
9379
9380   if (mp->is_ipv6)
9381     print (vam->ofp,
9382            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9383            ntohl (mp->rx_vrf_id),
9384            format_ip6_address, mp->dhcp_src_address,
9385            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9386   else
9387     print (vam->ofp,
9388            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9389            ntohl (mp->rx_vrf_id),
9390            format_ip4_address, mp->dhcp_src_address,
9391            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9392
9393   for (i = 0; i < count; i++)
9394     {
9395       s = &mp->servers[i];
9396
9397       if (mp->is_ipv6)
9398         print (vam->ofp,
9399                " Server Table-ID %d, Server Address %U",
9400                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9401       else
9402         print (vam->ofp,
9403                " Server Table-ID %d, Server Address %U",
9404                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9405     }
9406 }
9407
9408 static void vl_api_dhcp_proxy_details_t_handler_json
9409   (vl_api_dhcp_proxy_details_t * mp)
9410 {
9411   vat_main_t *vam = &vat_main;
9412   vat_json_node_t *node = NULL;
9413   u32 i, count = mp->count;
9414   struct in_addr ip4;
9415   struct in6_addr ip6;
9416   vl_api_dhcp_server_t *s;
9417
9418   if (VAT_JSON_ARRAY != vam->json_tree.type)
9419     {
9420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9421       vat_json_init_array (&vam->json_tree);
9422     }
9423   node = vat_json_array_add (&vam->json_tree);
9424
9425   vat_json_init_object (node);
9426   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9427   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9428   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9429
9430   if (mp->is_ipv6)
9431     {
9432       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9433       vat_json_object_add_ip6 (node, "src_address", ip6);
9434     }
9435   else
9436     {
9437       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9438       vat_json_object_add_ip4 (node, "src_address", ip4);
9439     }
9440
9441   for (i = 0; i < count; i++)
9442     {
9443       s = &mp->servers[i];
9444
9445       vat_json_object_add_uint (node, "server-table-id",
9446                                 ntohl (s->server_vrf_id));
9447
9448       if (mp->is_ipv6)
9449         {
9450           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9451           vat_json_object_add_ip4 (node, "src_address", ip4);
9452         }
9453       else
9454         {
9455           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9456           vat_json_object_add_ip6 (node, "server_address", ip6);
9457         }
9458     }
9459 }
9460
9461 static int
9462 api_dhcp_proxy_dump (vat_main_t * vam)
9463 {
9464   unformat_input_t *i = vam->input;
9465   vl_api_control_ping_t *mp_ping;
9466   vl_api_dhcp_proxy_dump_t *mp;
9467   u8 is_ipv6 = 0;
9468   int ret;
9469
9470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9471     {
9472       if (unformat (i, "ipv6"))
9473         is_ipv6 = 1;
9474       else
9475         {
9476           clib_warning ("parse error '%U'", format_unformat_error, i);
9477           return -99;
9478         }
9479     }
9480
9481   M (DHCP_PROXY_DUMP, mp);
9482
9483   mp->is_ip6 = is_ipv6;
9484   S (mp);
9485
9486   /* Use a control ping for synchronization */
9487   MPING (CONTROL_PING, mp_ping);
9488   S (mp_ping);
9489
9490   W (ret);
9491   return ret;
9492 }
9493
9494 static int
9495 api_dhcp_proxy_set_vss (vat_main_t * vam)
9496 {
9497   unformat_input_t *i = vam->input;
9498   vl_api_dhcp_proxy_set_vss_t *mp;
9499   u8 is_ipv6 = 0;
9500   u8 is_add = 1;
9501   u32 tbl_id;
9502   u8 tbl_id_set = 0;
9503   u32 oui;
9504   u8 oui_set = 0;
9505   u32 fib_id;
9506   u8 fib_id_set = 0;
9507   int ret;
9508
9509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (unformat (i, "tbl_id %d", &tbl_id))
9512         tbl_id_set = 1;
9513       if (unformat (i, "fib_id %d", &fib_id))
9514         fib_id_set = 1;
9515       if (unformat (i, "oui %d", &oui))
9516         oui_set = 1;
9517       else if (unformat (i, "ipv6"))
9518         is_ipv6 = 1;
9519       else if (unformat (i, "del"))
9520         is_add = 0;
9521       else
9522         {
9523           clib_warning ("parse error '%U'", format_unformat_error, i);
9524           return -99;
9525         }
9526     }
9527
9528   if (tbl_id_set == 0)
9529     {
9530       errmsg ("missing tbl id");
9531       return -99;
9532     }
9533
9534   if (fib_id_set == 0)
9535     {
9536       errmsg ("missing fib id");
9537       return -99;
9538     }
9539   if (oui_set == 0)
9540     {
9541       errmsg ("missing oui");
9542       return -99;
9543     }
9544
9545   M (DHCP_PROXY_SET_VSS, mp);
9546   mp->tbl_id = ntohl (tbl_id);
9547   mp->fib_id = ntohl (fib_id);
9548   mp->oui = ntohl (oui);
9549   mp->is_ipv6 = is_ipv6;
9550   mp->is_add = is_add;
9551
9552   S (mp);
9553   W (ret);
9554   return ret;
9555 }
9556
9557 static int
9558 api_dhcp_client_config (vat_main_t * vam)
9559 {
9560   unformat_input_t *i = vam->input;
9561   vl_api_dhcp_client_config_t *mp;
9562   u32 sw_if_index;
9563   u8 sw_if_index_set = 0;
9564   u8 is_add = 1;
9565   u8 *hostname = 0;
9566   u8 disable_event = 0;
9567   int ret;
9568
9569   /* Parse args required to build the message */
9570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9571     {
9572       if (unformat (i, "del"))
9573         is_add = 0;
9574       else
9575         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9576         sw_if_index_set = 1;
9577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9578         sw_if_index_set = 1;
9579       else if (unformat (i, "hostname %s", &hostname))
9580         ;
9581       else if (unformat (i, "disable_event"))
9582         disable_event = 1;
9583       else
9584         break;
9585     }
9586
9587   if (sw_if_index_set == 0)
9588     {
9589       errmsg ("missing interface name or sw_if_index");
9590       return -99;
9591     }
9592
9593   if (vec_len (hostname) > 63)
9594     {
9595       errmsg ("hostname too long");
9596     }
9597   vec_add1 (hostname, 0);
9598
9599   /* Construct the API message */
9600   M (DHCP_CLIENT_CONFIG, mp);
9601
9602   mp->sw_if_index = htonl (sw_if_index);
9603   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9604   vec_free (hostname);
9605   mp->is_add = is_add;
9606   mp->want_dhcp_event = disable_event ? 0 : 1;
9607   mp->pid = htonl (getpid ());
9608
9609   /* send it... */
9610   S (mp);
9611
9612   /* Wait for a reply, return good/bad news  */
9613   W (ret);
9614   return ret;
9615 }
9616
9617 static int
9618 api_set_ip_flow_hash (vat_main_t * vam)
9619 {
9620   unformat_input_t *i = vam->input;
9621   vl_api_set_ip_flow_hash_t *mp;
9622   u32 vrf_id = 0;
9623   u8 is_ipv6 = 0;
9624   u8 vrf_id_set = 0;
9625   u8 src = 0;
9626   u8 dst = 0;
9627   u8 sport = 0;
9628   u8 dport = 0;
9629   u8 proto = 0;
9630   u8 reverse = 0;
9631   int ret;
9632
9633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9634     {
9635       if (unformat (i, "vrf %d", &vrf_id))
9636         vrf_id_set = 1;
9637       else if (unformat (i, "ipv6"))
9638         is_ipv6 = 1;
9639       else if (unformat (i, "src"))
9640         src = 1;
9641       else if (unformat (i, "dst"))
9642         dst = 1;
9643       else if (unformat (i, "sport"))
9644         sport = 1;
9645       else if (unformat (i, "dport"))
9646         dport = 1;
9647       else if (unformat (i, "proto"))
9648         proto = 1;
9649       else if (unformat (i, "reverse"))
9650         reverse = 1;
9651
9652       else
9653         {
9654           clib_warning ("parse error '%U'", format_unformat_error, i);
9655           return -99;
9656         }
9657     }
9658
9659   if (vrf_id_set == 0)
9660     {
9661       errmsg ("missing vrf id");
9662       return -99;
9663     }
9664
9665   M (SET_IP_FLOW_HASH, mp);
9666   mp->src = src;
9667   mp->dst = dst;
9668   mp->sport = sport;
9669   mp->dport = dport;
9670   mp->proto = proto;
9671   mp->reverse = reverse;
9672   mp->vrf_id = ntohl (vrf_id);
9673   mp->is_ipv6 = is_ipv6;
9674
9675   S (mp);
9676   W (ret);
9677   return ret;
9678 }
9679
9680 static int
9681 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_sw_interface_ip6_enable_disable_t *mp;
9685   u32 sw_if_index;
9686   u8 sw_if_index_set = 0;
9687   u8 enable = 0;
9688   int ret;
9689
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9693         sw_if_index_set = 1;
9694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9695         sw_if_index_set = 1;
9696       else if (unformat (i, "enable"))
9697         enable = 1;
9698       else if (unformat (i, "disable"))
9699         enable = 0;
9700       else
9701         {
9702           clib_warning ("parse error '%U'", format_unformat_error, i);
9703           return -99;
9704         }
9705     }
9706
9707   if (sw_if_index_set == 0)
9708     {
9709       errmsg ("missing interface name or sw_if_index");
9710       return -99;
9711     }
9712
9713   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9714
9715   mp->sw_if_index = ntohl (sw_if_index);
9716   mp->enable = enable;
9717
9718   S (mp);
9719   W (ret);
9720   return ret;
9721 }
9722
9723 static int
9724 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9725 {
9726   unformat_input_t *i = vam->input;
9727   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9728   u32 sw_if_index;
9729   u8 sw_if_index_set = 0;
9730   u8 v6_address_set = 0;
9731   ip6_address_t v6address;
9732   int ret;
9733
9734   /* Parse args required to build the message */
9735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9736     {
9737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9738         sw_if_index_set = 1;
9739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9740         sw_if_index_set = 1;
9741       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9742         v6_address_set = 1;
9743       else
9744         break;
9745     }
9746
9747   if (sw_if_index_set == 0)
9748     {
9749       errmsg ("missing interface name or sw_if_index");
9750       return -99;
9751     }
9752   if (!v6_address_set)
9753     {
9754       errmsg ("no address set");
9755       return -99;
9756     }
9757
9758   /* Construct the API message */
9759   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9760
9761   mp->sw_if_index = ntohl (sw_if_index);
9762   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9763
9764   /* send it... */
9765   S (mp);
9766
9767   /* Wait for a reply, return good/bad news  */
9768   W (ret);
9769   return ret;
9770 }
9771
9772 static int
9773 api_ip6nd_proxy_add_del (vat_main_t * vam)
9774 {
9775   unformat_input_t *i = vam->input;
9776   vl_api_ip6nd_proxy_add_del_t *mp;
9777   u32 sw_if_index = ~0;
9778   u8 v6_address_set = 0;
9779   ip6_address_t v6address;
9780   u8 is_del = 0;
9781   int ret;
9782
9783   /* Parse args required to build the message */
9784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9785     {
9786       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9787         ;
9788       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9789         ;
9790       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9791         v6_address_set = 1;
9792       if (unformat (i, "del"))
9793         is_del = 1;
9794       else
9795         {
9796           clib_warning ("parse error '%U'", format_unformat_error, i);
9797           return -99;
9798         }
9799     }
9800
9801   if (sw_if_index == ~0)
9802     {
9803       errmsg ("missing interface name or sw_if_index");
9804       return -99;
9805     }
9806   if (!v6_address_set)
9807     {
9808       errmsg ("no address set");
9809       return -99;
9810     }
9811
9812   /* Construct the API message */
9813   M (IP6ND_PROXY_ADD_DEL, mp);
9814
9815   mp->is_del = is_del;
9816   mp->sw_if_index = ntohl (sw_if_index);
9817   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9818
9819   /* send it... */
9820   S (mp);
9821
9822   /* Wait for a reply, return good/bad news  */
9823   W (ret);
9824   return ret;
9825 }
9826
9827 static int
9828 api_ip6nd_proxy_dump (vat_main_t * vam)
9829 {
9830   vl_api_ip6nd_proxy_dump_t *mp;
9831   vl_api_control_ping_t *mp_ping;
9832   int ret;
9833
9834   M (IP6ND_PROXY_DUMP, mp);
9835
9836   S (mp);
9837
9838   /* Use a control ping for synchronization */
9839   MPING (CONTROL_PING, mp_ping);
9840   S (mp_ping);
9841
9842   W (ret);
9843   return ret;
9844 }
9845
9846 static void vl_api_ip6nd_proxy_details_t_handler
9847   (vl_api_ip6nd_proxy_details_t * mp)
9848 {
9849   vat_main_t *vam = &vat_main;
9850
9851   print (vam->ofp, "host %U sw_if_index %d",
9852          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9853 }
9854
9855 static void vl_api_ip6nd_proxy_details_t_handler_json
9856   (vl_api_ip6nd_proxy_details_t * mp)
9857 {
9858   vat_main_t *vam = &vat_main;
9859   struct in6_addr ip6;
9860   vat_json_node_t *node = NULL;
9861
9862   if (VAT_JSON_ARRAY != vam->json_tree.type)
9863     {
9864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9865       vat_json_init_array (&vam->json_tree);
9866     }
9867   node = vat_json_array_add (&vam->json_tree);
9868
9869   vat_json_init_object (node);
9870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9871
9872   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9873   vat_json_object_add_ip6 (node, "host", ip6);
9874 }
9875
9876 static int
9877 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9878 {
9879   unformat_input_t *i = vam->input;
9880   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9881   u32 sw_if_index;
9882   u8 sw_if_index_set = 0;
9883   u32 address_length = 0;
9884   u8 v6_address_set = 0;
9885   ip6_address_t v6address;
9886   u8 use_default = 0;
9887   u8 no_advertise = 0;
9888   u8 off_link = 0;
9889   u8 no_autoconfig = 0;
9890   u8 no_onlink = 0;
9891   u8 is_no = 0;
9892   u32 val_lifetime = 0;
9893   u32 pref_lifetime = 0;
9894   int ret;
9895
9896   /* Parse args required to build the message */
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "%U/%d",
9904                          unformat_ip6_address, &v6address, &address_length))
9905         v6_address_set = 1;
9906       else if (unformat (i, "val_life %d", &val_lifetime))
9907         ;
9908       else if (unformat (i, "pref_life %d", &pref_lifetime))
9909         ;
9910       else if (unformat (i, "def"))
9911         use_default = 1;
9912       else if (unformat (i, "noadv"))
9913         no_advertise = 1;
9914       else if (unformat (i, "offl"))
9915         off_link = 1;
9916       else if (unformat (i, "noauto"))
9917         no_autoconfig = 1;
9918       else if (unformat (i, "nolink"))
9919         no_onlink = 1;
9920       else if (unformat (i, "isno"))
9921         is_no = 1;
9922       else
9923         {
9924           clib_warning ("parse error '%U'", format_unformat_error, i);
9925           return -99;
9926         }
9927     }
9928
9929   if (sw_if_index_set == 0)
9930     {
9931       errmsg ("missing interface name or sw_if_index");
9932       return -99;
9933     }
9934   if (!v6_address_set)
9935     {
9936       errmsg ("no address set");
9937       return -99;
9938     }
9939
9940   /* Construct the API message */
9941   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9942
9943   mp->sw_if_index = ntohl (sw_if_index);
9944   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9945   mp->address_length = address_length;
9946   mp->use_default = use_default;
9947   mp->no_advertise = no_advertise;
9948   mp->off_link = off_link;
9949   mp->no_autoconfig = no_autoconfig;
9950   mp->no_onlink = no_onlink;
9951   mp->is_no = is_no;
9952   mp->val_lifetime = ntohl (val_lifetime);
9953   mp->pref_lifetime = ntohl (pref_lifetime);
9954
9955   /* send it... */
9956   S (mp);
9957
9958   /* Wait for a reply, return good/bad news  */
9959   W (ret);
9960   return ret;
9961 }
9962
9963 static int
9964 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9965 {
9966   unformat_input_t *i = vam->input;
9967   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9968   u32 sw_if_index;
9969   u8 sw_if_index_set = 0;
9970   u8 suppress = 0;
9971   u8 managed = 0;
9972   u8 other = 0;
9973   u8 ll_option = 0;
9974   u8 send_unicast = 0;
9975   u8 cease = 0;
9976   u8 is_no = 0;
9977   u8 default_router = 0;
9978   u32 max_interval = 0;
9979   u32 min_interval = 0;
9980   u32 lifetime = 0;
9981   u32 initial_count = 0;
9982   u32 initial_interval = 0;
9983   int ret;
9984
9985
9986   /* Parse args required to build the message */
9987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9988     {
9989       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9990         sw_if_index_set = 1;
9991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9992         sw_if_index_set = 1;
9993       else if (unformat (i, "maxint %d", &max_interval))
9994         ;
9995       else if (unformat (i, "minint %d", &min_interval))
9996         ;
9997       else if (unformat (i, "life %d", &lifetime))
9998         ;
9999       else if (unformat (i, "count %d", &initial_count))
10000         ;
10001       else if (unformat (i, "interval %d", &initial_interval))
10002         ;
10003       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10004         suppress = 1;
10005       else if (unformat (i, "managed"))
10006         managed = 1;
10007       else if (unformat (i, "other"))
10008         other = 1;
10009       else if (unformat (i, "ll"))
10010         ll_option = 1;
10011       else if (unformat (i, "send"))
10012         send_unicast = 1;
10013       else if (unformat (i, "cease"))
10014         cease = 1;
10015       else if (unformat (i, "isno"))
10016         is_no = 1;
10017       else if (unformat (i, "def"))
10018         default_router = 1;
10019       else
10020         {
10021           clib_warning ("parse error '%U'", format_unformat_error, i);
10022           return -99;
10023         }
10024     }
10025
10026   if (sw_if_index_set == 0)
10027     {
10028       errmsg ("missing interface name or sw_if_index");
10029       return -99;
10030     }
10031
10032   /* Construct the API message */
10033   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10034
10035   mp->sw_if_index = ntohl (sw_if_index);
10036   mp->max_interval = ntohl (max_interval);
10037   mp->min_interval = ntohl (min_interval);
10038   mp->lifetime = ntohl (lifetime);
10039   mp->initial_count = ntohl (initial_count);
10040   mp->initial_interval = ntohl (initial_interval);
10041   mp->suppress = suppress;
10042   mp->managed = managed;
10043   mp->other = other;
10044   mp->ll_option = ll_option;
10045   mp->send_unicast = send_unicast;
10046   mp->cease = cease;
10047   mp->is_no = is_no;
10048   mp->default_router = default_router;
10049
10050   /* send it... */
10051   S (mp);
10052
10053   /* Wait for a reply, return good/bad news  */
10054   W (ret);
10055   return ret;
10056 }
10057
10058 static int
10059 api_set_arp_neighbor_limit (vat_main_t * vam)
10060 {
10061   unformat_input_t *i = vam->input;
10062   vl_api_set_arp_neighbor_limit_t *mp;
10063   u32 arp_nbr_limit;
10064   u8 limit_set = 0;
10065   u8 is_ipv6 = 0;
10066   int ret;
10067
10068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10069     {
10070       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10071         limit_set = 1;
10072       else if (unformat (i, "ipv6"))
10073         is_ipv6 = 1;
10074       else
10075         {
10076           clib_warning ("parse error '%U'", format_unformat_error, i);
10077           return -99;
10078         }
10079     }
10080
10081   if (limit_set == 0)
10082     {
10083       errmsg ("missing limit value");
10084       return -99;
10085     }
10086
10087   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10088
10089   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10090   mp->is_ipv6 = is_ipv6;
10091
10092   S (mp);
10093   W (ret);
10094   return ret;
10095 }
10096
10097 static int
10098 api_l2_patch_add_del (vat_main_t * vam)
10099 {
10100   unformat_input_t *i = vam->input;
10101   vl_api_l2_patch_add_del_t *mp;
10102   u32 rx_sw_if_index;
10103   u8 rx_sw_if_index_set = 0;
10104   u32 tx_sw_if_index;
10105   u8 tx_sw_if_index_set = 0;
10106   u8 is_add = 1;
10107   int ret;
10108
10109   /* Parse args required to build the message */
10110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10111     {
10112       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10113         rx_sw_if_index_set = 1;
10114       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10115         tx_sw_if_index_set = 1;
10116       else if (unformat (i, "rx"))
10117         {
10118           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10119             {
10120               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10121                             &rx_sw_if_index))
10122                 rx_sw_if_index_set = 1;
10123             }
10124           else
10125             break;
10126         }
10127       else if (unformat (i, "tx"))
10128         {
10129           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10130             {
10131               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10132                             &tx_sw_if_index))
10133                 tx_sw_if_index_set = 1;
10134             }
10135           else
10136             break;
10137         }
10138       else if (unformat (i, "del"))
10139         is_add = 0;
10140       else
10141         break;
10142     }
10143
10144   if (rx_sw_if_index_set == 0)
10145     {
10146       errmsg ("missing rx interface name or rx_sw_if_index");
10147       return -99;
10148     }
10149
10150   if (tx_sw_if_index_set == 0)
10151     {
10152       errmsg ("missing tx interface name or tx_sw_if_index");
10153       return -99;
10154     }
10155
10156   M (L2_PATCH_ADD_DEL, mp);
10157
10158   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10159   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10160   mp->is_add = is_add;
10161
10162   S (mp);
10163   W (ret);
10164   return ret;
10165 }
10166
10167 u8 is_del;
10168 u8 localsid_addr[16];
10169 u8 end_psp;
10170 u8 behavior;
10171 u32 sw_if_index;
10172 u32 vlan_index;
10173 u32 fib_table;
10174 u8 nh_addr[16];
10175
10176 static int
10177 api_sr_localsid_add_del (vat_main_t * vam)
10178 {
10179   unformat_input_t *i = vam->input;
10180   vl_api_sr_localsid_add_del_t *mp;
10181
10182   u8 is_del;
10183   ip6_address_t localsid;
10184   u8 end_psp = 0;
10185   u8 behavior = ~0;
10186   u32 sw_if_index;
10187   u32 fib_table = ~(u32) 0;
10188   ip6_address_t next_hop;
10189
10190   bool nexthop_set = 0;
10191
10192   int ret;
10193
10194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (i, "del"))
10197         is_del = 1;
10198       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10199       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10200         nexthop_set = 1;
10201       else if (unformat (i, "behavior %u", &behavior));
10202       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10203       else if (unformat (i, "fib-table %u", &fib_table));
10204       else if (unformat (i, "end.psp %u", &behavior));
10205       else
10206         break;
10207     }
10208
10209   M (SR_LOCALSID_ADD_DEL, mp);
10210
10211   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10212   if (nexthop_set)
10213     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10214   mp->behavior = behavior;
10215   mp->sw_if_index = ntohl (sw_if_index);
10216   mp->fib_table = ntohl (fib_table);
10217   mp->end_psp = end_psp;
10218   mp->is_del = is_del;
10219
10220   S (mp);
10221   W (ret);
10222   return ret;
10223 }
10224
10225 static int
10226 api_ioam_enable (vat_main_t * vam)
10227 {
10228   unformat_input_t *input = vam->input;
10229   vl_api_ioam_enable_t *mp;
10230   u32 id = 0;
10231   int has_trace_option = 0;
10232   int has_pot_option = 0;
10233   int has_seqno_option = 0;
10234   int has_analyse_option = 0;
10235   int ret;
10236
10237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10238     {
10239       if (unformat (input, "trace"))
10240         has_trace_option = 1;
10241       else if (unformat (input, "pot"))
10242         has_pot_option = 1;
10243       else if (unformat (input, "seqno"))
10244         has_seqno_option = 1;
10245       else if (unformat (input, "analyse"))
10246         has_analyse_option = 1;
10247       else
10248         break;
10249     }
10250   M (IOAM_ENABLE, mp);
10251   mp->id = htons (id);
10252   mp->seqno = has_seqno_option;
10253   mp->analyse = has_analyse_option;
10254   mp->pot_enable = has_pot_option;
10255   mp->trace_enable = has_trace_option;
10256
10257   S (mp);
10258   W (ret);
10259   return ret;
10260 }
10261
10262
10263 static int
10264 api_ioam_disable (vat_main_t * vam)
10265 {
10266   vl_api_ioam_disable_t *mp;
10267   int ret;
10268
10269   M (IOAM_DISABLE, mp);
10270   S (mp);
10271   W (ret);
10272   return ret;
10273 }
10274
10275 #define foreach_tcp_proto_field                 \
10276 _(src_port)                                     \
10277 _(dst_port)
10278
10279 #define foreach_udp_proto_field                 \
10280 _(src_port)                                     \
10281 _(dst_port)
10282
10283 #define foreach_ip4_proto_field                 \
10284 _(src_address)                                  \
10285 _(dst_address)                                  \
10286 _(tos)                                          \
10287 _(length)                                       \
10288 _(fragment_id)                                  \
10289 _(ttl)                                          \
10290 _(protocol)                                     \
10291 _(checksum)
10292
10293 typedef struct
10294 {
10295   u16 src_port, dst_port;
10296 } tcpudp_header_t;
10297
10298 #if VPP_API_TEST_BUILTIN == 0
10299 uword
10300 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10301 {
10302   u8 **maskp = va_arg (*args, u8 **);
10303   u8 *mask = 0;
10304   u8 found_something = 0;
10305   tcp_header_t *tcp;
10306
10307 #define _(a) u8 a=0;
10308   foreach_tcp_proto_field;
10309 #undef _
10310
10311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10312     {
10313       if (0);
10314 #define _(a) else if (unformat (input, #a)) a=1;
10315       foreach_tcp_proto_field
10316 #undef _
10317         else
10318         break;
10319     }
10320
10321 #define _(a) found_something += a;
10322   foreach_tcp_proto_field;
10323 #undef _
10324
10325   if (found_something == 0)
10326     return 0;
10327
10328   vec_validate (mask, sizeof (*tcp) - 1);
10329
10330   tcp = (tcp_header_t *) mask;
10331
10332 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10333   foreach_tcp_proto_field;
10334 #undef _
10335
10336   *maskp = mask;
10337   return 1;
10338 }
10339
10340 uword
10341 unformat_udp_mask (unformat_input_t * input, va_list * args)
10342 {
10343   u8 **maskp = va_arg (*args, u8 **);
10344   u8 *mask = 0;
10345   u8 found_something = 0;
10346   udp_header_t *udp;
10347
10348 #define _(a) u8 a=0;
10349   foreach_udp_proto_field;
10350 #undef _
10351
10352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10353     {
10354       if (0);
10355 #define _(a) else if (unformat (input, #a)) a=1;
10356       foreach_udp_proto_field
10357 #undef _
10358         else
10359         break;
10360     }
10361
10362 #define _(a) found_something += a;
10363   foreach_udp_proto_field;
10364 #undef _
10365
10366   if (found_something == 0)
10367     return 0;
10368
10369   vec_validate (mask, sizeof (*udp) - 1);
10370
10371   udp = (udp_header_t *) mask;
10372
10373 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10374   foreach_udp_proto_field;
10375 #undef _
10376
10377   *maskp = mask;
10378   return 1;
10379 }
10380
10381 uword
10382 unformat_l4_mask (unformat_input_t * input, va_list * args)
10383 {
10384   u8 **maskp = va_arg (*args, u8 **);
10385   u16 src_port = 0, dst_port = 0;
10386   tcpudp_header_t *tcpudp;
10387
10388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10389     {
10390       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10391         return 1;
10392       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10393         return 1;
10394       else if (unformat (input, "src_port"))
10395         src_port = 0xFFFF;
10396       else if (unformat (input, "dst_port"))
10397         dst_port = 0xFFFF;
10398       else
10399         return 0;
10400     }
10401
10402   if (!src_port && !dst_port)
10403     return 0;
10404
10405   u8 *mask = 0;
10406   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10407
10408   tcpudp = (tcpudp_header_t *) mask;
10409   tcpudp->src_port = src_port;
10410   tcpudp->dst_port = dst_port;
10411
10412   *maskp = mask;
10413
10414   return 1;
10415 }
10416
10417 uword
10418 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10419 {
10420   u8 **maskp = va_arg (*args, u8 **);
10421   u8 *mask = 0;
10422   u8 found_something = 0;
10423   ip4_header_t *ip;
10424
10425 #define _(a) u8 a=0;
10426   foreach_ip4_proto_field;
10427 #undef _
10428   u8 version = 0;
10429   u8 hdr_length = 0;
10430
10431
10432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10433     {
10434       if (unformat (input, "version"))
10435         version = 1;
10436       else if (unformat (input, "hdr_length"))
10437         hdr_length = 1;
10438       else if (unformat (input, "src"))
10439         src_address = 1;
10440       else if (unformat (input, "dst"))
10441         dst_address = 1;
10442       else if (unformat (input, "proto"))
10443         protocol = 1;
10444
10445 #define _(a) else if (unformat (input, #a)) a=1;
10446       foreach_ip4_proto_field
10447 #undef _
10448         else
10449         break;
10450     }
10451
10452 #define _(a) found_something += a;
10453   foreach_ip4_proto_field;
10454 #undef _
10455
10456   if (found_something == 0)
10457     return 0;
10458
10459   vec_validate (mask, sizeof (*ip) - 1);
10460
10461   ip = (ip4_header_t *) mask;
10462
10463 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10464   foreach_ip4_proto_field;
10465 #undef _
10466
10467   ip->ip_version_and_header_length = 0;
10468
10469   if (version)
10470     ip->ip_version_and_header_length |= 0xF0;
10471
10472   if (hdr_length)
10473     ip->ip_version_and_header_length |= 0x0F;
10474
10475   *maskp = mask;
10476   return 1;
10477 }
10478
10479 #define foreach_ip6_proto_field                 \
10480 _(src_address)                                  \
10481 _(dst_address)                                  \
10482 _(payload_length)                               \
10483 _(hop_limit)                                    \
10484 _(protocol)
10485
10486 uword
10487 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10488 {
10489   u8 **maskp = va_arg (*args, u8 **);
10490   u8 *mask = 0;
10491   u8 found_something = 0;
10492   ip6_header_t *ip;
10493   u32 ip_version_traffic_class_and_flow_label;
10494
10495 #define _(a) u8 a=0;
10496   foreach_ip6_proto_field;
10497 #undef _
10498   u8 version = 0;
10499   u8 traffic_class = 0;
10500   u8 flow_label = 0;
10501
10502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10503     {
10504       if (unformat (input, "version"))
10505         version = 1;
10506       else if (unformat (input, "traffic-class"))
10507         traffic_class = 1;
10508       else if (unformat (input, "flow-label"))
10509         flow_label = 1;
10510       else if (unformat (input, "src"))
10511         src_address = 1;
10512       else if (unformat (input, "dst"))
10513         dst_address = 1;
10514       else if (unformat (input, "proto"))
10515         protocol = 1;
10516
10517 #define _(a) else if (unformat (input, #a)) a=1;
10518       foreach_ip6_proto_field
10519 #undef _
10520         else
10521         break;
10522     }
10523
10524 #define _(a) found_something += a;
10525   foreach_ip6_proto_field;
10526 #undef _
10527
10528   if (found_something == 0)
10529     return 0;
10530
10531   vec_validate (mask, sizeof (*ip) - 1);
10532
10533   ip = (ip6_header_t *) mask;
10534
10535 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10536   foreach_ip6_proto_field;
10537 #undef _
10538
10539   ip_version_traffic_class_and_flow_label = 0;
10540
10541   if (version)
10542     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10543
10544   if (traffic_class)
10545     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10546
10547   if (flow_label)
10548     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10549
10550   ip->ip_version_traffic_class_and_flow_label =
10551     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10552
10553   *maskp = mask;
10554   return 1;
10555 }
10556
10557 uword
10558 unformat_l3_mask (unformat_input_t * input, va_list * args)
10559 {
10560   u8 **maskp = va_arg (*args, u8 **);
10561
10562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10565         return 1;
10566       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10567         return 1;
10568       else
10569         break;
10570     }
10571   return 0;
10572 }
10573
10574 uword
10575 unformat_l2_mask (unformat_input_t * input, va_list * args)
10576 {
10577   u8 **maskp = va_arg (*args, u8 **);
10578   u8 *mask = 0;
10579   u8 src = 0;
10580   u8 dst = 0;
10581   u8 proto = 0;
10582   u8 tag1 = 0;
10583   u8 tag2 = 0;
10584   u8 ignore_tag1 = 0;
10585   u8 ignore_tag2 = 0;
10586   u8 cos1 = 0;
10587   u8 cos2 = 0;
10588   u8 dot1q = 0;
10589   u8 dot1ad = 0;
10590   int len = 14;
10591
10592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (input, "src"))
10595         src = 1;
10596       else if (unformat (input, "dst"))
10597         dst = 1;
10598       else if (unformat (input, "proto"))
10599         proto = 1;
10600       else if (unformat (input, "tag1"))
10601         tag1 = 1;
10602       else if (unformat (input, "tag2"))
10603         tag2 = 1;
10604       else if (unformat (input, "ignore-tag1"))
10605         ignore_tag1 = 1;
10606       else if (unformat (input, "ignore-tag2"))
10607         ignore_tag2 = 1;
10608       else if (unformat (input, "cos1"))
10609         cos1 = 1;
10610       else if (unformat (input, "cos2"))
10611         cos2 = 1;
10612       else if (unformat (input, "dot1q"))
10613         dot1q = 1;
10614       else if (unformat (input, "dot1ad"))
10615         dot1ad = 1;
10616       else
10617         break;
10618     }
10619   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10620        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10621     return 0;
10622
10623   if (tag1 || ignore_tag1 || cos1 || dot1q)
10624     len = 18;
10625   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10626     len = 22;
10627
10628   vec_validate (mask, len - 1);
10629
10630   if (dst)
10631     memset (mask, 0xff, 6);
10632
10633   if (src)
10634     memset (mask + 6, 0xff, 6);
10635
10636   if (tag2 || dot1ad)
10637     {
10638       /* inner vlan tag */
10639       if (tag2)
10640         {
10641           mask[19] = 0xff;
10642           mask[18] = 0x0f;
10643         }
10644       if (cos2)
10645         mask[18] |= 0xe0;
10646       if (proto)
10647         mask[21] = mask[20] = 0xff;
10648       if (tag1)
10649         {
10650           mask[15] = 0xff;
10651           mask[14] = 0x0f;
10652         }
10653       if (cos1)
10654         mask[14] |= 0xe0;
10655       *maskp = mask;
10656       return 1;
10657     }
10658   if (tag1 | dot1q)
10659     {
10660       if (tag1)
10661         {
10662           mask[15] = 0xff;
10663           mask[14] = 0x0f;
10664         }
10665       if (cos1)
10666         mask[14] |= 0xe0;
10667       if (proto)
10668         mask[16] = mask[17] = 0xff;
10669
10670       *maskp = mask;
10671       return 1;
10672     }
10673   if (cos2)
10674     mask[18] |= 0xe0;
10675   if (cos1)
10676     mask[14] |= 0xe0;
10677   if (proto)
10678     mask[12] = mask[13] = 0xff;
10679
10680   *maskp = mask;
10681   return 1;
10682 }
10683
10684 uword
10685 unformat_classify_mask (unformat_input_t * input, va_list * args)
10686 {
10687   u8 **maskp = va_arg (*args, u8 **);
10688   u32 *skipp = va_arg (*args, u32 *);
10689   u32 *matchp = va_arg (*args, u32 *);
10690   u32 match;
10691   u8 *mask = 0;
10692   u8 *l2 = 0;
10693   u8 *l3 = 0;
10694   u8 *l4 = 0;
10695   int i;
10696
10697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10700         ;
10701       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10702         ;
10703       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10704         ;
10705       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10706         ;
10707       else
10708         break;
10709     }
10710
10711   if (l4 && !l3)
10712     {
10713       vec_free (mask);
10714       vec_free (l2);
10715       vec_free (l4);
10716       return 0;
10717     }
10718
10719   if (mask || l2 || l3 || l4)
10720     {
10721       if (l2 || l3 || l4)
10722         {
10723           /* "With a free Ethernet header in every package" */
10724           if (l2 == 0)
10725             vec_validate (l2, 13);
10726           mask = l2;
10727           if (vec_len (l3))
10728             {
10729               vec_append (mask, l3);
10730               vec_free (l3);
10731             }
10732           if (vec_len (l4))
10733             {
10734               vec_append (mask, l4);
10735               vec_free (l4);
10736             }
10737         }
10738
10739       /* Scan forward looking for the first significant mask octet */
10740       for (i = 0; i < vec_len (mask); i++)
10741         if (mask[i])
10742           break;
10743
10744       /* compute (skip, match) params */
10745       *skipp = i / sizeof (u32x4);
10746       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10747
10748       /* Pad mask to an even multiple of the vector size */
10749       while (vec_len (mask) % sizeof (u32x4))
10750         vec_add1 (mask, 0);
10751
10752       match = vec_len (mask) / sizeof (u32x4);
10753
10754       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10755         {
10756           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10757           if (*tmp || *(tmp + 1))
10758             break;
10759           match--;
10760         }
10761       if (match == 0)
10762         clib_warning ("BUG: match 0");
10763
10764       _vec_len (mask) = match * sizeof (u32x4);
10765
10766       *matchp = match;
10767       *maskp = mask;
10768
10769       return 1;
10770     }
10771
10772   return 0;
10773 }
10774 #endif /* VPP_API_TEST_BUILTIN */
10775
10776 #define foreach_l2_next                         \
10777 _(drop, DROP)                                   \
10778 _(ethernet, ETHERNET_INPUT)                     \
10779 _(ip4, IP4_INPUT)                               \
10780 _(ip6, IP6_INPUT)
10781
10782 uword
10783 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10784 {
10785   u32 *miss_next_indexp = va_arg (*args, u32 *);
10786   u32 next_index = 0;
10787   u32 tmp;
10788
10789 #define _(n,N) \
10790   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10791   foreach_l2_next;
10792 #undef _
10793
10794   if (unformat (input, "%d", &tmp))
10795     {
10796       next_index = tmp;
10797       goto out;
10798     }
10799
10800   return 0;
10801
10802 out:
10803   *miss_next_indexp = next_index;
10804   return 1;
10805 }
10806
10807 #define foreach_ip_next                         \
10808 _(drop, DROP)                                   \
10809 _(local, LOCAL)                                 \
10810 _(rewrite, REWRITE)
10811
10812 uword
10813 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10814 {
10815   u32 *miss_next_indexp = va_arg (*args, u32 *);
10816   u32 next_index = 0;
10817   u32 tmp;
10818
10819 #define _(n,N) \
10820   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10821   foreach_ip_next;
10822 #undef _
10823
10824   if (unformat (input, "%d", &tmp))
10825     {
10826       next_index = tmp;
10827       goto out;
10828     }
10829
10830   return 0;
10831
10832 out:
10833   *miss_next_indexp = next_index;
10834   return 1;
10835 }
10836
10837 #define foreach_acl_next                        \
10838 _(deny, DENY)
10839
10840 uword
10841 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10842 {
10843   u32 *miss_next_indexp = va_arg (*args, u32 *);
10844   u32 next_index = 0;
10845   u32 tmp;
10846
10847 #define _(n,N) \
10848   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10849   foreach_acl_next;
10850 #undef _
10851
10852   if (unformat (input, "permit"))
10853     {
10854       next_index = ~0;
10855       goto out;
10856     }
10857   else if (unformat (input, "%d", &tmp))
10858     {
10859       next_index = tmp;
10860       goto out;
10861     }
10862
10863   return 0;
10864
10865 out:
10866   *miss_next_indexp = next_index;
10867   return 1;
10868 }
10869
10870 uword
10871 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10872 {
10873   u32 *r = va_arg (*args, u32 *);
10874
10875   if (unformat (input, "conform-color"))
10876     *r = POLICE_CONFORM;
10877   else if (unformat (input, "exceed-color"))
10878     *r = POLICE_EXCEED;
10879   else
10880     return 0;
10881
10882   return 1;
10883 }
10884
10885 static int
10886 api_classify_add_del_table (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_classify_add_del_table_t *mp;
10890
10891   u32 nbuckets = 2;
10892   u32 skip = ~0;
10893   u32 match = ~0;
10894   int is_add = 1;
10895   int del_chain = 0;
10896   u32 table_index = ~0;
10897   u32 next_table_index = ~0;
10898   u32 miss_next_index = ~0;
10899   u32 memory_size = 32 << 20;
10900   u8 *mask = 0;
10901   u32 current_data_flag = 0;
10902   int current_data_offset = 0;
10903   int ret;
10904
10905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906     {
10907       if (unformat (i, "del"))
10908         is_add = 0;
10909       else if (unformat (i, "del-chain"))
10910         {
10911           is_add = 0;
10912           del_chain = 1;
10913         }
10914       else if (unformat (i, "buckets %d", &nbuckets))
10915         ;
10916       else if (unformat (i, "memory_size %d", &memory_size))
10917         ;
10918       else if (unformat (i, "skip %d", &skip))
10919         ;
10920       else if (unformat (i, "match %d", &match))
10921         ;
10922       else if (unformat (i, "table %d", &table_index))
10923         ;
10924       else if (unformat (i, "mask %U", unformat_classify_mask,
10925                          &mask, &skip, &match))
10926         ;
10927       else if (unformat (i, "next-table %d", &next_table_index))
10928         ;
10929       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10930                          &miss_next_index))
10931         ;
10932       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10933                          &miss_next_index))
10934         ;
10935       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10936                          &miss_next_index))
10937         ;
10938       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10939         ;
10940       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10941         ;
10942       else
10943         break;
10944     }
10945
10946   if (is_add && mask == 0)
10947     {
10948       errmsg ("Mask required");
10949       return -99;
10950     }
10951
10952   if (is_add && skip == ~0)
10953     {
10954       errmsg ("skip count required");
10955       return -99;
10956     }
10957
10958   if (is_add && match == ~0)
10959     {
10960       errmsg ("match count required");
10961       return -99;
10962     }
10963
10964   if (!is_add && table_index == ~0)
10965     {
10966       errmsg ("table index required for delete");
10967       return -99;
10968     }
10969
10970   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10971
10972   mp->is_add = is_add;
10973   mp->del_chain = del_chain;
10974   mp->table_index = ntohl (table_index);
10975   mp->nbuckets = ntohl (nbuckets);
10976   mp->memory_size = ntohl (memory_size);
10977   mp->skip_n_vectors = ntohl (skip);
10978   mp->match_n_vectors = ntohl (match);
10979   mp->next_table_index = ntohl (next_table_index);
10980   mp->miss_next_index = ntohl (miss_next_index);
10981   mp->current_data_flag = ntohl (current_data_flag);
10982   mp->current_data_offset = ntohl (current_data_offset);
10983   clib_memcpy (mp->mask, mask, vec_len (mask));
10984
10985   vec_free (mask);
10986
10987   S (mp);
10988   W (ret);
10989   return ret;
10990 }
10991
10992 #if VPP_API_TEST_BUILTIN == 0
10993 uword
10994 unformat_l4_match (unformat_input_t * input, va_list * args)
10995 {
10996   u8 **matchp = va_arg (*args, u8 **);
10997
10998   u8 *proto_header = 0;
10999   int src_port = 0;
11000   int dst_port = 0;
11001
11002   tcpudp_header_t h;
11003
11004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11005     {
11006       if (unformat (input, "src_port %d", &src_port))
11007         ;
11008       else if (unformat (input, "dst_port %d", &dst_port))
11009         ;
11010       else
11011         return 0;
11012     }
11013
11014   h.src_port = clib_host_to_net_u16 (src_port);
11015   h.dst_port = clib_host_to_net_u16 (dst_port);
11016   vec_validate (proto_header, sizeof (h) - 1);
11017   memcpy (proto_header, &h, sizeof (h));
11018
11019   *matchp = proto_header;
11020
11021   return 1;
11022 }
11023
11024 uword
11025 unformat_ip4_match (unformat_input_t * input, va_list * args)
11026 {
11027   u8 **matchp = va_arg (*args, u8 **);
11028   u8 *match = 0;
11029   ip4_header_t *ip;
11030   int version = 0;
11031   u32 version_val;
11032   int hdr_length = 0;
11033   u32 hdr_length_val;
11034   int src = 0, dst = 0;
11035   ip4_address_t src_val, dst_val;
11036   int proto = 0;
11037   u32 proto_val;
11038   int tos = 0;
11039   u32 tos_val;
11040   int length = 0;
11041   u32 length_val;
11042   int fragment_id = 0;
11043   u32 fragment_id_val;
11044   int ttl = 0;
11045   int ttl_val;
11046   int checksum = 0;
11047   u32 checksum_val;
11048
11049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11050     {
11051       if (unformat (input, "version %d", &version_val))
11052         version = 1;
11053       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11054         hdr_length = 1;
11055       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11056         src = 1;
11057       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11058         dst = 1;
11059       else if (unformat (input, "proto %d", &proto_val))
11060         proto = 1;
11061       else if (unformat (input, "tos %d", &tos_val))
11062         tos = 1;
11063       else if (unformat (input, "length %d", &length_val))
11064         length = 1;
11065       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11066         fragment_id = 1;
11067       else if (unformat (input, "ttl %d", &ttl_val))
11068         ttl = 1;
11069       else if (unformat (input, "checksum %d", &checksum_val))
11070         checksum = 1;
11071       else
11072         break;
11073     }
11074
11075   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11076       + ttl + checksum == 0)
11077     return 0;
11078
11079   /*
11080    * Aligned because we use the real comparison functions
11081    */
11082   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11083
11084   ip = (ip4_header_t *) match;
11085
11086   /* These are realistically matched in practice */
11087   if (src)
11088     ip->src_address.as_u32 = src_val.as_u32;
11089
11090   if (dst)
11091     ip->dst_address.as_u32 = dst_val.as_u32;
11092
11093   if (proto)
11094     ip->protocol = proto_val;
11095
11096
11097   /* These are not, but they're included for completeness */
11098   if (version)
11099     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11100
11101   if (hdr_length)
11102     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11103
11104   if (tos)
11105     ip->tos = tos_val;
11106
11107   if (length)
11108     ip->length = clib_host_to_net_u16 (length_val);
11109
11110   if (ttl)
11111     ip->ttl = ttl_val;
11112
11113   if (checksum)
11114     ip->checksum = clib_host_to_net_u16 (checksum_val);
11115
11116   *matchp = match;
11117   return 1;
11118 }
11119
11120 uword
11121 unformat_ip6_match (unformat_input_t * input, va_list * args)
11122 {
11123   u8 **matchp = va_arg (*args, u8 **);
11124   u8 *match = 0;
11125   ip6_header_t *ip;
11126   int version = 0;
11127   u32 version_val;
11128   u8 traffic_class = 0;
11129   u32 traffic_class_val = 0;
11130   u8 flow_label = 0;
11131   u8 flow_label_val;
11132   int src = 0, dst = 0;
11133   ip6_address_t src_val, dst_val;
11134   int proto = 0;
11135   u32 proto_val;
11136   int payload_length = 0;
11137   u32 payload_length_val;
11138   int hop_limit = 0;
11139   int hop_limit_val;
11140   u32 ip_version_traffic_class_and_flow_label;
11141
11142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11143     {
11144       if (unformat (input, "version %d", &version_val))
11145         version = 1;
11146       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11147         traffic_class = 1;
11148       else if (unformat (input, "flow_label %d", &flow_label_val))
11149         flow_label = 1;
11150       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11151         src = 1;
11152       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11153         dst = 1;
11154       else if (unformat (input, "proto %d", &proto_val))
11155         proto = 1;
11156       else if (unformat (input, "payload_length %d", &payload_length_val))
11157         payload_length = 1;
11158       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11159         hop_limit = 1;
11160       else
11161         break;
11162     }
11163
11164   if (version + traffic_class + flow_label + src + dst + proto +
11165       payload_length + hop_limit == 0)
11166     return 0;
11167
11168   /*
11169    * Aligned because we use the real comparison functions
11170    */
11171   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11172
11173   ip = (ip6_header_t *) match;
11174
11175   if (src)
11176     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11177
11178   if (dst)
11179     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11180
11181   if (proto)
11182     ip->protocol = proto_val;
11183
11184   ip_version_traffic_class_and_flow_label = 0;
11185
11186   if (version)
11187     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11188
11189   if (traffic_class)
11190     ip_version_traffic_class_and_flow_label |=
11191       (traffic_class_val & 0xFF) << 20;
11192
11193   if (flow_label)
11194     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11195
11196   ip->ip_version_traffic_class_and_flow_label =
11197     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11198
11199   if (payload_length)
11200     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11201
11202   if (hop_limit)
11203     ip->hop_limit = hop_limit_val;
11204
11205   *matchp = match;
11206   return 1;
11207 }
11208
11209 uword
11210 unformat_l3_match (unformat_input_t * input, va_list * args)
11211 {
11212   u8 **matchp = va_arg (*args, u8 **);
11213
11214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11215     {
11216       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11217         return 1;
11218       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11219         return 1;
11220       else
11221         break;
11222     }
11223   return 0;
11224 }
11225
11226 uword
11227 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11228 {
11229   u8 *tagp = va_arg (*args, u8 *);
11230   u32 tag;
11231
11232   if (unformat (input, "%d", &tag))
11233     {
11234       tagp[0] = (tag >> 8) & 0x0F;
11235       tagp[1] = tag & 0xFF;
11236       return 1;
11237     }
11238
11239   return 0;
11240 }
11241
11242 uword
11243 unformat_l2_match (unformat_input_t * input, va_list * args)
11244 {
11245   u8 **matchp = va_arg (*args, u8 **);
11246   u8 *match = 0;
11247   u8 src = 0;
11248   u8 src_val[6];
11249   u8 dst = 0;
11250   u8 dst_val[6];
11251   u8 proto = 0;
11252   u16 proto_val;
11253   u8 tag1 = 0;
11254   u8 tag1_val[2];
11255   u8 tag2 = 0;
11256   u8 tag2_val[2];
11257   int len = 14;
11258   u8 ignore_tag1 = 0;
11259   u8 ignore_tag2 = 0;
11260   u8 cos1 = 0;
11261   u8 cos2 = 0;
11262   u32 cos1_val = 0;
11263   u32 cos2_val = 0;
11264
11265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11266     {
11267       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11268         src = 1;
11269       else
11270         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11271         dst = 1;
11272       else if (unformat (input, "proto %U",
11273                          unformat_ethernet_type_host_byte_order, &proto_val))
11274         proto = 1;
11275       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11276         tag1 = 1;
11277       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11278         tag2 = 1;
11279       else if (unformat (input, "ignore-tag1"))
11280         ignore_tag1 = 1;
11281       else if (unformat (input, "ignore-tag2"))
11282         ignore_tag2 = 1;
11283       else if (unformat (input, "cos1 %d", &cos1_val))
11284         cos1 = 1;
11285       else if (unformat (input, "cos2 %d", &cos2_val))
11286         cos2 = 1;
11287       else
11288         break;
11289     }
11290   if ((src + dst + proto + tag1 + tag2 +
11291        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11292     return 0;
11293
11294   if (tag1 || ignore_tag1 || cos1)
11295     len = 18;
11296   if (tag2 || ignore_tag2 || cos2)
11297     len = 22;
11298
11299   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11300
11301   if (dst)
11302     clib_memcpy (match, dst_val, 6);
11303
11304   if (src)
11305     clib_memcpy (match + 6, src_val, 6);
11306
11307   if (tag2)
11308     {
11309       /* inner vlan tag */
11310       match[19] = tag2_val[1];
11311       match[18] = tag2_val[0];
11312       if (cos2)
11313         match[18] |= (cos2_val & 0x7) << 5;
11314       if (proto)
11315         {
11316           match[21] = proto_val & 0xff;
11317           match[20] = proto_val >> 8;
11318         }
11319       if (tag1)
11320         {
11321           match[15] = tag1_val[1];
11322           match[14] = tag1_val[0];
11323         }
11324       if (cos1)
11325         match[14] |= (cos1_val & 0x7) << 5;
11326       *matchp = match;
11327       return 1;
11328     }
11329   if (tag1)
11330     {
11331       match[15] = tag1_val[1];
11332       match[14] = tag1_val[0];
11333       if (proto)
11334         {
11335           match[17] = proto_val & 0xff;
11336           match[16] = proto_val >> 8;
11337         }
11338       if (cos1)
11339         match[14] |= (cos1_val & 0x7) << 5;
11340
11341       *matchp = match;
11342       return 1;
11343     }
11344   if (cos2)
11345     match[18] |= (cos2_val & 0x7) << 5;
11346   if (cos1)
11347     match[14] |= (cos1_val & 0x7) << 5;
11348   if (proto)
11349     {
11350       match[13] = proto_val & 0xff;
11351       match[12] = proto_val >> 8;
11352     }
11353
11354   *matchp = match;
11355   return 1;
11356 }
11357 #endif
11358
11359 uword
11360 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11361 {
11362   u8 **matchp = va_arg (*args, u8 **);
11363   u32 skip_n_vectors = va_arg (*args, u32);
11364   u32 match_n_vectors = va_arg (*args, u32);
11365
11366   u8 *match = 0;
11367   u8 *l2 = 0;
11368   u8 *l3 = 0;
11369   u8 *l4 = 0;
11370
11371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11372     {
11373       if (unformat (input, "hex %U", unformat_hex_string, &match))
11374         ;
11375       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11376         ;
11377       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11378         ;
11379       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11380         ;
11381       else
11382         break;
11383     }
11384
11385   if (l4 && !l3)
11386     {
11387       vec_free (match);
11388       vec_free (l2);
11389       vec_free (l4);
11390       return 0;
11391     }
11392
11393   if (match || l2 || l3 || l4)
11394     {
11395       if (l2 || l3 || l4)
11396         {
11397           /* "Win a free Ethernet header in every packet" */
11398           if (l2 == 0)
11399             vec_validate_aligned (l2, 13, sizeof (u32x4));
11400           match = l2;
11401           if (vec_len (l3))
11402             {
11403               vec_append_aligned (match, l3, sizeof (u32x4));
11404               vec_free (l3);
11405             }
11406           if (vec_len (l4))
11407             {
11408               vec_append_aligned (match, l4, sizeof (u32x4));
11409               vec_free (l4);
11410             }
11411         }
11412
11413       /* Make sure the vector is big enough even if key is all 0's */
11414       vec_validate_aligned
11415         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11416          sizeof (u32x4));
11417
11418       /* Set size, include skipped vectors */
11419       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11420
11421       *matchp = match;
11422
11423       return 1;
11424     }
11425
11426   return 0;
11427 }
11428
11429 static int
11430 api_classify_add_del_session (vat_main_t * vam)
11431 {
11432   unformat_input_t *i = vam->input;
11433   vl_api_classify_add_del_session_t *mp;
11434   int is_add = 1;
11435   u32 table_index = ~0;
11436   u32 hit_next_index = ~0;
11437   u32 opaque_index = ~0;
11438   u8 *match = 0;
11439   i32 advance = 0;
11440   u32 skip_n_vectors = 0;
11441   u32 match_n_vectors = 0;
11442   u32 action = 0;
11443   u32 metadata = 0;
11444   int ret;
11445
11446   /*
11447    * Warning: you have to supply skip_n and match_n
11448    * because the API client cant simply look at the classify
11449    * table object.
11450    */
11451
11452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11453     {
11454       if (unformat (i, "del"))
11455         is_add = 0;
11456       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11457                          &hit_next_index))
11458         ;
11459       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11460                          &hit_next_index))
11461         ;
11462       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11463                          &hit_next_index))
11464         ;
11465       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11466         ;
11467       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11468         ;
11469       else if (unformat (i, "opaque-index %d", &opaque_index))
11470         ;
11471       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11472         ;
11473       else if (unformat (i, "match_n %d", &match_n_vectors))
11474         ;
11475       else if (unformat (i, "match %U", api_unformat_classify_match,
11476                          &match, skip_n_vectors, match_n_vectors))
11477         ;
11478       else if (unformat (i, "advance %d", &advance))
11479         ;
11480       else if (unformat (i, "table-index %d", &table_index))
11481         ;
11482       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11483         action = 1;
11484       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11485         action = 2;
11486       else if (unformat (i, "action %d", &action))
11487         ;
11488       else if (unformat (i, "metadata %d", &metadata))
11489         ;
11490       else
11491         break;
11492     }
11493
11494   if (table_index == ~0)
11495     {
11496       errmsg ("Table index required");
11497       return -99;
11498     }
11499
11500   if (is_add && match == 0)
11501     {
11502       errmsg ("Match value required");
11503       return -99;
11504     }
11505
11506   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11507
11508   mp->is_add = is_add;
11509   mp->table_index = ntohl (table_index);
11510   mp->hit_next_index = ntohl (hit_next_index);
11511   mp->opaque_index = ntohl (opaque_index);
11512   mp->advance = ntohl (advance);
11513   mp->action = action;
11514   mp->metadata = ntohl (metadata);
11515   clib_memcpy (mp->match, match, vec_len (match));
11516   vec_free (match);
11517
11518   S (mp);
11519   W (ret);
11520   return ret;
11521 }
11522
11523 static int
11524 api_classify_set_interface_ip_table (vat_main_t * vam)
11525 {
11526   unformat_input_t *i = vam->input;
11527   vl_api_classify_set_interface_ip_table_t *mp;
11528   u32 sw_if_index;
11529   int sw_if_index_set;
11530   u32 table_index = ~0;
11531   u8 is_ipv6 = 0;
11532   int ret;
11533
11534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11535     {
11536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11537         sw_if_index_set = 1;
11538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11539         sw_if_index_set = 1;
11540       else if (unformat (i, "table %d", &table_index))
11541         ;
11542       else
11543         {
11544           clib_warning ("parse error '%U'", format_unformat_error, i);
11545           return -99;
11546         }
11547     }
11548
11549   if (sw_if_index_set == 0)
11550     {
11551       errmsg ("missing interface name or sw_if_index");
11552       return -99;
11553     }
11554
11555
11556   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11557
11558   mp->sw_if_index = ntohl (sw_if_index);
11559   mp->table_index = ntohl (table_index);
11560   mp->is_ipv6 = is_ipv6;
11561
11562   S (mp);
11563   W (ret);
11564   return ret;
11565 }
11566
11567 static int
11568 api_classify_set_interface_l2_tables (vat_main_t * vam)
11569 {
11570   unformat_input_t *i = vam->input;
11571   vl_api_classify_set_interface_l2_tables_t *mp;
11572   u32 sw_if_index;
11573   int sw_if_index_set;
11574   u32 ip4_table_index = ~0;
11575   u32 ip6_table_index = ~0;
11576   u32 other_table_index = ~0;
11577   u32 is_input = 1;
11578   int ret;
11579
11580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11581     {
11582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11583         sw_if_index_set = 1;
11584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11585         sw_if_index_set = 1;
11586       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11587         ;
11588       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11589         ;
11590       else if (unformat (i, "other-table %d", &other_table_index))
11591         ;
11592       else if (unformat (i, "is-input %d", &is_input))
11593         ;
11594       else
11595         {
11596           clib_warning ("parse error '%U'", format_unformat_error, i);
11597           return -99;
11598         }
11599     }
11600
11601   if (sw_if_index_set == 0)
11602     {
11603       errmsg ("missing interface name or sw_if_index");
11604       return -99;
11605     }
11606
11607
11608   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11609
11610   mp->sw_if_index = ntohl (sw_if_index);
11611   mp->ip4_table_index = ntohl (ip4_table_index);
11612   mp->ip6_table_index = ntohl (ip6_table_index);
11613   mp->other_table_index = ntohl (other_table_index);
11614   mp->is_input = (u8) is_input;
11615
11616   S (mp);
11617   W (ret);
11618   return ret;
11619 }
11620
11621 static int
11622 api_set_ipfix_exporter (vat_main_t * vam)
11623 {
11624   unformat_input_t *i = vam->input;
11625   vl_api_set_ipfix_exporter_t *mp;
11626   ip4_address_t collector_address;
11627   u8 collector_address_set = 0;
11628   u32 collector_port = ~0;
11629   ip4_address_t src_address;
11630   u8 src_address_set = 0;
11631   u32 vrf_id = ~0;
11632   u32 path_mtu = ~0;
11633   u32 template_interval = ~0;
11634   u8 udp_checksum = 0;
11635   int ret;
11636
11637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11638     {
11639       if (unformat (i, "collector_address %U", unformat_ip4_address,
11640                     &collector_address))
11641         collector_address_set = 1;
11642       else if (unformat (i, "collector_port %d", &collector_port))
11643         ;
11644       else if (unformat (i, "src_address %U", unformat_ip4_address,
11645                          &src_address))
11646         src_address_set = 1;
11647       else if (unformat (i, "vrf_id %d", &vrf_id))
11648         ;
11649       else if (unformat (i, "path_mtu %d", &path_mtu))
11650         ;
11651       else if (unformat (i, "template_interval %d", &template_interval))
11652         ;
11653       else if (unformat (i, "udp_checksum"))
11654         udp_checksum = 1;
11655       else
11656         break;
11657     }
11658
11659   if (collector_address_set == 0)
11660     {
11661       errmsg ("collector_address required");
11662       return -99;
11663     }
11664
11665   if (src_address_set == 0)
11666     {
11667       errmsg ("src_address required");
11668       return -99;
11669     }
11670
11671   M (SET_IPFIX_EXPORTER, mp);
11672
11673   memcpy (mp->collector_address, collector_address.data,
11674           sizeof (collector_address.data));
11675   mp->collector_port = htons ((u16) collector_port);
11676   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11677   mp->vrf_id = htonl (vrf_id);
11678   mp->path_mtu = htonl (path_mtu);
11679   mp->template_interval = htonl (template_interval);
11680   mp->udp_checksum = udp_checksum;
11681
11682   S (mp);
11683   W (ret);
11684   return ret;
11685 }
11686
11687 static int
11688 api_set_ipfix_classify_stream (vat_main_t * vam)
11689 {
11690   unformat_input_t *i = vam->input;
11691   vl_api_set_ipfix_classify_stream_t *mp;
11692   u32 domain_id = 0;
11693   u32 src_port = UDP_DST_PORT_ipfix;
11694   int ret;
11695
11696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11697     {
11698       if (unformat (i, "domain %d", &domain_id))
11699         ;
11700       else if (unformat (i, "src_port %d", &src_port))
11701         ;
11702       else
11703         {
11704           errmsg ("unknown input `%U'", format_unformat_error, i);
11705           return -99;
11706         }
11707     }
11708
11709   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11710
11711   mp->domain_id = htonl (domain_id);
11712   mp->src_port = htons ((u16) src_port);
11713
11714   S (mp);
11715   W (ret);
11716   return ret;
11717 }
11718
11719 static int
11720 api_ipfix_classify_table_add_del (vat_main_t * vam)
11721 {
11722   unformat_input_t *i = vam->input;
11723   vl_api_ipfix_classify_table_add_del_t *mp;
11724   int is_add = -1;
11725   u32 classify_table_index = ~0;
11726   u8 ip_version = 0;
11727   u8 transport_protocol = 255;
11728   int ret;
11729
11730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11731     {
11732       if (unformat (i, "add"))
11733         is_add = 1;
11734       else if (unformat (i, "del"))
11735         is_add = 0;
11736       else if (unformat (i, "table %d", &classify_table_index))
11737         ;
11738       else if (unformat (i, "ip4"))
11739         ip_version = 4;
11740       else if (unformat (i, "ip6"))
11741         ip_version = 6;
11742       else if (unformat (i, "tcp"))
11743         transport_protocol = 6;
11744       else if (unformat (i, "udp"))
11745         transport_protocol = 17;
11746       else
11747         {
11748           errmsg ("unknown input `%U'", format_unformat_error, i);
11749           return -99;
11750         }
11751     }
11752
11753   if (is_add == -1)
11754     {
11755       errmsg ("expecting: add|del");
11756       return -99;
11757     }
11758   if (classify_table_index == ~0)
11759     {
11760       errmsg ("classifier table not specified");
11761       return -99;
11762     }
11763   if (ip_version == 0)
11764     {
11765       errmsg ("IP version not specified");
11766       return -99;
11767     }
11768
11769   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11770
11771   mp->is_add = is_add;
11772   mp->table_id = htonl (classify_table_index);
11773   mp->ip_version = ip_version;
11774   mp->transport_protocol = transport_protocol;
11775
11776   S (mp);
11777   W (ret);
11778   return ret;
11779 }
11780
11781 static int
11782 api_get_node_index (vat_main_t * vam)
11783 {
11784   unformat_input_t *i = vam->input;
11785   vl_api_get_node_index_t *mp;
11786   u8 *name = 0;
11787   int ret;
11788
11789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11790     {
11791       if (unformat (i, "node %s", &name))
11792         ;
11793       else
11794         break;
11795     }
11796   if (name == 0)
11797     {
11798       errmsg ("node name required");
11799       return -99;
11800     }
11801   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11802     {
11803       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11804       return -99;
11805     }
11806
11807   M (GET_NODE_INDEX, mp);
11808   clib_memcpy (mp->node_name, name, vec_len (name));
11809   vec_free (name);
11810
11811   S (mp);
11812   W (ret);
11813   return ret;
11814 }
11815
11816 static int
11817 api_get_next_index (vat_main_t * vam)
11818 {
11819   unformat_input_t *i = vam->input;
11820   vl_api_get_next_index_t *mp;
11821   u8 *node_name = 0, *next_node_name = 0;
11822   int ret;
11823
11824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (i, "node-name %s", &node_name))
11827         ;
11828       else if (unformat (i, "next-node-name %s", &next_node_name))
11829         break;
11830     }
11831
11832   if (node_name == 0)
11833     {
11834       errmsg ("node name required");
11835       return -99;
11836     }
11837   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11838     {
11839       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11840       return -99;
11841     }
11842
11843   if (next_node_name == 0)
11844     {
11845       errmsg ("next node name required");
11846       return -99;
11847     }
11848   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11849     {
11850       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11851       return -99;
11852     }
11853
11854   M (GET_NEXT_INDEX, mp);
11855   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11856   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11857   vec_free (node_name);
11858   vec_free (next_node_name);
11859
11860   S (mp);
11861   W (ret);
11862   return ret;
11863 }
11864
11865 static int
11866 api_add_node_next (vat_main_t * vam)
11867 {
11868   unformat_input_t *i = vam->input;
11869   vl_api_add_node_next_t *mp;
11870   u8 *name = 0;
11871   u8 *next = 0;
11872   int ret;
11873
11874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11875     {
11876       if (unformat (i, "node %s", &name))
11877         ;
11878       else if (unformat (i, "next %s", &next))
11879         ;
11880       else
11881         break;
11882     }
11883   if (name == 0)
11884     {
11885       errmsg ("node name required");
11886       return -99;
11887     }
11888   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11889     {
11890       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11891       return -99;
11892     }
11893   if (next == 0)
11894     {
11895       errmsg ("next node required");
11896       return -99;
11897     }
11898   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11899     {
11900       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11901       return -99;
11902     }
11903
11904   M (ADD_NODE_NEXT, mp);
11905   clib_memcpy (mp->node_name, name, vec_len (name));
11906   clib_memcpy (mp->next_name, next, vec_len (next));
11907   vec_free (name);
11908   vec_free (next);
11909
11910   S (mp);
11911   W (ret);
11912   return ret;
11913 }
11914
11915 static int
11916 api_l2tpv3_create_tunnel (vat_main_t * vam)
11917 {
11918   unformat_input_t *i = vam->input;
11919   ip6_address_t client_address, our_address;
11920   int client_address_set = 0;
11921   int our_address_set = 0;
11922   u32 local_session_id = 0;
11923   u32 remote_session_id = 0;
11924   u64 local_cookie = 0;
11925   u64 remote_cookie = 0;
11926   u8 l2_sublayer_present = 0;
11927   vl_api_l2tpv3_create_tunnel_t *mp;
11928   int ret;
11929
11930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11931     {
11932       if (unformat (i, "client_address %U", unformat_ip6_address,
11933                     &client_address))
11934         client_address_set = 1;
11935       else if (unformat (i, "our_address %U", unformat_ip6_address,
11936                          &our_address))
11937         our_address_set = 1;
11938       else if (unformat (i, "local_session_id %d", &local_session_id))
11939         ;
11940       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11941         ;
11942       else if (unformat (i, "local_cookie %lld", &local_cookie))
11943         ;
11944       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11945         ;
11946       else if (unformat (i, "l2-sublayer-present"))
11947         l2_sublayer_present = 1;
11948       else
11949         break;
11950     }
11951
11952   if (client_address_set == 0)
11953     {
11954       errmsg ("client_address required");
11955       return -99;
11956     }
11957
11958   if (our_address_set == 0)
11959     {
11960       errmsg ("our_address required");
11961       return -99;
11962     }
11963
11964   M (L2TPV3_CREATE_TUNNEL, mp);
11965
11966   clib_memcpy (mp->client_address, client_address.as_u8,
11967                sizeof (mp->client_address));
11968
11969   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11970
11971   mp->local_session_id = ntohl (local_session_id);
11972   mp->remote_session_id = ntohl (remote_session_id);
11973   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11974   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11975   mp->l2_sublayer_present = l2_sublayer_present;
11976   mp->is_ipv6 = 1;
11977
11978   S (mp);
11979   W (ret);
11980   return ret;
11981 }
11982
11983 static int
11984 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11985 {
11986   unformat_input_t *i = vam->input;
11987   u32 sw_if_index;
11988   u8 sw_if_index_set = 0;
11989   u64 new_local_cookie = 0;
11990   u64 new_remote_cookie = 0;
11991   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11992   int ret;
11993
11994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11995     {
11996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11997         sw_if_index_set = 1;
11998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11999         sw_if_index_set = 1;
12000       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12001         ;
12002       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12003         ;
12004       else
12005         break;
12006     }
12007
12008   if (sw_if_index_set == 0)
12009     {
12010       errmsg ("missing interface name or sw_if_index");
12011       return -99;
12012     }
12013
12014   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12015
12016   mp->sw_if_index = ntohl (sw_if_index);
12017   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12018   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12019
12020   S (mp);
12021   W (ret);
12022   return ret;
12023 }
12024
12025 static int
12026 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12027 {
12028   unformat_input_t *i = vam->input;
12029   vl_api_l2tpv3_interface_enable_disable_t *mp;
12030   u32 sw_if_index;
12031   u8 sw_if_index_set = 0;
12032   u8 enable_disable = 1;
12033   int ret;
12034
12035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12036     {
12037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12040         sw_if_index_set = 1;
12041       else if (unformat (i, "enable"))
12042         enable_disable = 1;
12043       else if (unformat (i, "disable"))
12044         enable_disable = 0;
12045       else
12046         break;
12047     }
12048
12049   if (sw_if_index_set == 0)
12050     {
12051       errmsg ("missing interface name or sw_if_index");
12052       return -99;
12053     }
12054
12055   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12056
12057   mp->sw_if_index = ntohl (sw_if_index);
12058   mp->enable_disable = enable_disable;
12059
12060   S (mp);
12061   W (ret);
12062   return ret;
12063 }
12064
12065 static int
12066 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12067 {
12068   unformat_input_t *i = vam->input;
12069   vl_api_l2tpv3_set_lookup_key_t *mp;
12070   u8 key = ~0;
12071   int ret;
12072
12073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12074     {
12075       if (unformat (i, "lookup_v6_src"))
12076         key = L2T_LOOKUP_SRC_ADDRESS;
12077       else if (unformat (i, "lookup_v6_dst"))
12078         key = L2T_LOOKUP_DST_ADDRESS;
12079       else if (unformat (i, "lookup_session_id"))
12080         key = L2T_LOOKUP_SESSION_ID;
12081       else
12082         break;
12083     }
12084
12085   if (key == (u8) ~ 0)
12086     {
12087       errmsg ("l2tp session lookup key unset");
12088       return -99;
12089     }
12090
12091   M (L2TPV3_SET_LOOKUP_KEY, mp);
12092
12093   mp->key = key;
12094
12095   S (mp);
12096   W (ret);
12097   return ret;
12098 }
12099
12100 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12101   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12102 {
12103   vat_main_t *vam = &vat_main;
12104
12105   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12106          format_ip6_address, mp->our_address,
12107          format_ip6_address, mp->client_address,
12108          clib_net_to_host_u32 (mp->sw_if_index));
12109
12110   print (vam->ofp,
12111          "   local cookies %016llx %016llx remote cookie %016llx",
12112          clib_net_to_host_u64 (mp->local_cookie[0]),
12113          clib_net_to_host_u64 (mp->local_cookie[1]),
12114          clib_net_to_host_u64 (mp->remote_cookie));
12115
12116   print (vam->ofp, "   local session-id %d remote session-id %d",
12117          clib_net_to_host_u32 (mp->local_session_id),
12118          clib_net_to_host_u32 (mp->remote_session_id));
12119
12120   print (vam->ofp, "   l2 specific sublayer %s\n",
12121          mp->l2_sublayer_present ? "preset" : "absent");
12122
12123 }
12124
12125 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12126   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12127 {
12128   vat_main_t *vam = &vat_main;
12129   vat_json_node_t *node = NULL;
12130   struct in6_addr addr;
12131
12132   if (VAT_JSON_ARRAY != vam->json_tree.type)
12133     {
12134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12135       vat_json_init_array (&vam->json_tree);
12136     }
12137   node = vat_json_array_add (&vam->json_tree);
12138
12139   vat_json_init_object (node);
12140
12141   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12142   vat_json_object_add_ip6 (node, "our_address", addr);
12143   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12144   vat_json_object_add_ip6 (node, "client_address", addr);
12145
12146   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12147   vat_json_init_array (lc);
12148   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12149   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12150   vat_json_object_add_uint (node, "remote_cookie",
12151                             clib_net_to_host_u64 (mp->remote_cookie));
12152
12153   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12154   vat_json_object_add_uint (node, "local_session_id",
12155                             clib_net_to_host_u32 (mp->local_session_id));
12156   vat_json_object_add_uint (node, "remote_session_id",
12157                             clib_net_to_host_u32 (mp->remote_session_id));
12158   vat_json_object_add_string_copy (node, "l2_sublayer",
12159                                    mp->l2_sublayer_present ? (u8 *) "present"
12160                                    : (u8 *) "absent");
12161 }
12162
12163 static int
12164 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12165 {
12166   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12167   vl_api_control_ping_t *mp_ping;
12168   int ret;
12169
12170   /* Get list of l2tpv3-tunnel interfaces */
12171   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12172   S (mp);
12173
12174   /* Use a control ping for synchronization */
12175   MPING (CONTROL_PING, mp_ping);
12176   S (mp_ping);
12177
12178   W (ret);
12179   return ret;
12180 }
12181
12182
12183 static void vl_api_sw_interface_tap_details_t_handler
12184   (vl_api_sw_interface_tap_details_t * mp)
12185 {
12186   vat_main_t *vam = &vat_main;
12187
12188   print (vam->ofp, "%-16s %d",
12189          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12190 }
12191
12192 static void vl_api_sw_interface_tap_details_t_handler_json
12193   (vl_api_sw_interface_tap_details_t * mp)
12194 {
12195   vat_main_t *vam = &vat_main;
12196   vat_json_node_t *node = NULL;
12197
12198   if (VAT_JSON_ARRAY != vam->json_tree.type)
12199     {
12200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12201       vat_json_init_array (&vam->json_tree);
12202     }
12203   node = vat_json_array_add (&vam->json_tree);
12204
12205   vat_json_init_object (node);
12206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12207   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12208 }
12209
12210 static int
12211 api_sw_interface_tap_dump (vat_main_t * vam)
12212 {
12213   vl_api_sw_interface_tap_dump_t *mp;
12214   vl_api_control_ping_t *mp_ping;
12215   int ret;
12216
12217   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12218   /* Get list of tap interfaces */
12219   M (SW_INTERFACE_TAP_DUMP, mp);
12220   S (mp);
12221
12222   /* Use a control ping for synchronization */
12223   MPING (CONTROL_PING, mp_ping);
12224   S (mp_ping);
12225
12226   W (ret);
12227   return ret;
12228 }
12229
12230 static uword unformat_vxlan_decap_next
12231   (unformat_input_t * input, va_list * args)
12232 {
12233   u32 *result = va_arg (*args, u32 *);
12234   u32 tmp;
12235
12236   if (unformat (input, "l2"))
12237     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12238   else if (unformat (input, "%d", &tmp))
12239     *result = tmp;
12240   else
12241     return 0;
12242   return 1;
12243 }
12244
12245 static int
12246 api_vxlan_add_del_tunnel (vat_main_t * vam)
12247 {
12248   unformat_input_t *line_input = vam->input;
12249   vl_api_vxlan_add_del_tunnel_t *mp;
12250   ip46_address_t src, dst;
12251   u8 is_add = 1;
12252   u8 ipv4_set = 0, ipv6_set = 0;
12253   u8 src_set = 0;
12254   u8 dst_set = 0;
12255   u8 grp_set = 0;
12256   u32 mcast_sw_if_index = ~0;
12257   u32 encap_vrf_id = 0;
12258   u32 decap_next_index = ~0;
12259   u32 vni = 0;
12260   int ret;
12261
12262   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12263   memset (&src, 0, sizeof src);
12264   memset (&dst, 0, sizeof dst);
12265
12266   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12267     {
12268       if (unformat (line_input, "del"))
12269         is_add = 0;
12270       else
12271         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12272         {
12273           ipv4_set = 1;
12274           src_set = 1;
12275         }
12276       else
12277         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12278         {
12279           ipv4_set = 1;
12280           dst_set = 1;
12281         }
12282       else
12283         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12284         {
12285           ipv6_set = 1;
12286           src_set = 1;
12287         }
12288       else
12289         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12290         {
12291           ipv6_set = 1;
12292           dst_set = 1;
12293         }
12294       else if (unformat (line_input, "group %U %U",
12295                          unformat_ip4_address, &dst.ip4,
12296                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12297         {
12298           grp_set = dst_set = 1;
12299           ipv4_set = 1;
12300         }
12301       else if (unformat (line_input, "group %U",
12302                          unformat_ip4_address, &dst.ip4))
12303         {
12304           grp_set = dst_set = 1;
12305           ipv4_set = 1;
12306         }
12307       else if (unformat (line_input, "group %U %U",
12308                          unformat_ip6_address, &dst.ip6,
12309                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12310         {
12311           grp_set = dst_set = 1;
12312           ipv6_set = 1;
12313         }
12314       else if (unformat (line_input, "group %U",
12315                          unformat_ip6_address, &dst.ip6))
12316         {
12317           grp_set = dst_set = 1;
12318           ipv6_set = 1;
12319         }
12320       else
12321         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12322         ;
12323       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12324         ;
12325       else if (unformat (line_input, "decap-next %U",
12326                          unformat_vxlan_decap_next, &decap_next_index))
12327         ;
12328       else if (unformat (line_input, "vni %d", &vni))
12329         ;
12330       else
12331         {
12332           errmsg ("parse error '%U'", format_unformat_error, line_input);
12333           return -99;
12334         }
12335     }
12336
12337   if (src_set == 0)
12338     {
12339       errmsg ("tunnel src address not specified");
12340       return -99;
12341     }
12342   if (dst_set == 0)
12343     {
12344       errmsg ("tunnel dst address not specified");
12345       return -99;
12346     }
12347
12348   if (grp_set && !ip46_address_is_multicast (&dst))
12349     {
12350       errmsg ("tunnel group address not multicast");
12351       return -99;
12352     }
12353   if (grp_set && mcast_sw_if_index == ~0)
12354     {
12355       errmsg ("tunnel nonexistent multicast device");
12356       return -99;
12357     }
12358   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12359     {
12360       errmsg ("tunnel dst address must be unicast");
12361       return -99;
12362     }
12363
12364
12365   if (ipv4_set && ipv6_set)
12366     {
12367       errmsg ("both IPv4 and IPv6 addresses specified");
12368       return -99;
12369     }
12370
12371   if ((vni == 0) || (vni >> 24))
12372     {
12373       errmsg ("vni not specified or out of range");
12374       return -99;
12375     }
12376
12377   M (VXLAN_ADD_DEL_TUNNEL, mp);
12378
12379   if (ipv6_set)
12380     {
12381       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12382       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12383     }
12384   else
12385     {
12386       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12387       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12388     }
12389   mp->encap_vrf_id = ntohl (encap_vrf_id);
12390   mp->decap_next_index = ntohl (decap_next_index);
12391   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12392   mp->vni = ntohl (vni);
12393   mp->is_add = is_add;
12394   mp->is_ipv6 = ipv6_set;
12395
12396   S (mp);
12397   W (ret);
12398   return ret;
12399 }
12400
12401 static void vl_api_vxlan_tunnel_details_t_handler
12402   (vl_api_vxlan_tunnel_details_t * mp)
12403 {
12404   vat_main_t *vam = &vat_main;
12405   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12406   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12407
12408   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12409          ntohl (mp->sw_if_index),
12410          format_ip46_address, &src, IP46_TYPE_ANY,
12411          format_ip46_address, &dst, IP46_TYPE_ANY,
12412          ntohl (mp->encap_vrf_id),
12413          ntohl (mp->decap_next_index), ntohl (mp->vni),
12414          ntohl (mp->mcast_sw_if_index));
12415 }
12416
12417 static void vl_api_vxlan_tunnel_details_t_handler_json
12418   (vl_api_vxlan_tunnel_details_t * mp)
12419 {
12420   vat_main_t *vam = &vat_main;
12421   vat_json_node_t *node = NULL;
12422
12423   if (VAT_JSON_ARRAY != vam->json_tree.type)
12424     {
12425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12426       vat_json_init_array (&vam->json_tree);
12427     }
12428   node = vat_json_array_add (&vam->json_tree);
12429
12430   vat_json_init_object (node);
12431   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12432   if (mp->is_ipv6)
12433     {
12434       struct in6_addr ip6;
12435
12436       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12437       vat_json_object_add_ip6 (node, "src_address", ip6);
12438       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12439       vat_json_object_add_ip6 (node, "dst_address", ip6);
12440     }
12441   else
12442     {
12443       struct in_addr ip4;
12444
12445       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12446       vat_json_object_add_ip4 (node, "src_address", ip4);
12447       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12448       vat_json_object_add_ip4 (node, "dst_address", ip4);
12449     }
12450   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12451   vat_json_object_add_uint (node, "decap_next_index",
12452                             ntohl (mp->decap_next_index));
12453   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12454   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12455   vat_json_object_add_uint (node, "mcast_sw_if_index",
12456                             ntohl (mp->mcast_sw_if_index));
12457 }
12458
12459 static int
12460 api_vxlan_tunnel_dump (vat_main_t * vam)
12461 {
12462   unformat_input_t *i = vam->input;
12463   vl_api_vxlan_tunnel_dump_t *mp;
12464   vl_api_control_ping_t *mp_ping;
12465   u32 sw_if_index;
12466   u8 sw_if_index_set = 0;
12467   int ret;
12468
12469   /* Parse args required to build the message */
12470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12471     {
12472       if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         sw_if_index_set = 1;
12474       else
12475         break;
12476     }
12477
12478   if (sw_if_index_set == 0)
12479     {
12480       sw_if_index = ~0;
12481     }
12482
12483   if (!vam->json_output)
12484     {
12485       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12486              "sw_if_index", "src_address", "dst_address",
12487              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12488     }
12489
12490   /* Get list of vxlan-tunnel interfaces */
12491   M (VXLAN_TUNNEL_DUMP, mp);
12492
12493   mp->sw_if_index = htonl (sw_if_index);
12494
12495   S (mp);
12496
12497   /* Use a control ping for synchronization */
12498   MPING (CONTROL_PING, mp_ping);
12499   S (mp_ping);
12500
12501   W (ret);
12502   return ret;
12503 }
12504
12505 static uword unformat_geneve_decap_next
12506   (unformat_input_t * input, va_list * args)
12507 {
12508   u32 *result = va_arg (*args, u32 *);
12509   u32 tmp;
12510
12511   if (unformat (input, "l2"))
12512     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12513   else if (unformat (input, "%d", &tmp))
12514     *result = tmp;
12515   else
12516     return 0;
12517   return 1;
12518 }
12519
12520 static int
12521 api_geneve_add_del_tunnel (vat_main_t * vam)
12522 {
12523   unformat_input_t *line_input = vam->input;
12524   vl_api_geneve_add_del_tunnel_t *mp;
12525   ip46_address_t src, dst;
12526   u8 is_add = 1;
12527   u8 ipv4_set = 0, ipv6_set = 0;
12528   u8 src_set = 0;
12529   u8 dst_set = 0;
12530   u8 grp_set = 0;
12531   u32 mcast_sw_if_index = ~0;
12532   u32 encap_vrf_id = 0;
12533   u32 decap_next_index = ~0;
12534   u32 vni = 0;
12535   int ret;
12536
12537   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12538   memset (&src, 0, sizeof src);
12539   memset (&dst, 0, sizeof dst);
12540
12541   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12542     {
12543       if (unformat (line_input, "del"))
12544         is_add = 0;
12545       else
12546         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12547         {
12548           ipv4_set = 1;
12549           src_set = 1;
12550         }
12551       else
12552         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12553         {
12554           ipv4_set = 1;
12555           dst_set = 1;
12556         }
12557       else
12558         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12559         {
12560           ipv6_set = 1;
12561           src_set = 1;
12562         }
12563       else
12564         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12565         {
12566           ipv6_set = 1;
12567           dst_set = 1;
12568         }
12569       else if (unformat (line_input, "group %U %U",
12570                          unformat_ip4_address, &dst.ip4,
12571                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12572         {
12573           grp_set = dst_set = 1;
12574           ipv4_set = 1;
12575         }
12576       else if (unformat (line_input, "group %U",
12577                          unformat_ip4_address, &dst.ip4))
12578         {
12579           grp_set = dst_set = 1;
12580           ipv4_set = 1;
12581         }
12582       else if (unformat (line_input, "group %U %U",
12583                          unformat_ip6_address, &dst.ip6,
12584                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12585         {
12586           grp_set = dst_set = 1;
12587           ipv6_set = 1;
12588         }
12589       else if (unformat (line_input, "group %U",
12590                          unformat_ip6_address, &dst.ip6))
12591         {
12592           grp_set = dst_set = 1;
12593           ipv6_set = 1;
12594         }
12595       else
12596         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12597         ;
12598       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12599         ;
12600       else if (unformat (line_input, "decap-next %U",
12601                          unformat_geneve_decap_next, &decap_next_index))
12602         ;
12603       else if (unformat (line_input, "vni %d", &vni))
12604         ;
12605       else
12606         {
12607           errmsg ("parse error '%U'", format_unformat_error, line_input);
12608           return -99;
12609         }
12610     }
12611
12612   if (src_set == 0)
12613     {
12614       errmsg ("tunnel src address not specified");
12615       return -99;
12616     }
12617   if (dst_set == 0)
12618     {
12619       errmsg ("tunnel dst address not specified");
12620       return -99;
12621     }
12622
12623   if (grp_set && !ip46_address_is_multicast (&dst))
12624     {
12625       errmsg ("tunnel group address not multicast");
12626       return -99;
12627     }
12628   if (grp_set && mcast_sw_if_index == ~0)
12629     {
12630       errmsg ("tunnel nonexistent multicast device");
12631       return -99;
12632     }
12633   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12634     {
12635       errmsg ("tunnel dst address must be unicast");
12636       return -99;
12637     }
12638
12639
12640   if (ipv4_set && ipv6_set)
12641     {
12642       errmsg ("both IPv4 and IPv6 addresses specified");
12643       return -99;
12644     }
12645
12646   if ((vni == 0) || (vni >> 24))
12647     {
12648       errmsg ("vni not specified or out of range");
12649       return -99;
12650     }
12651
12652   M (GENEVE_ADD_DEL_TUNNEL, mp);
12653
12654   if (ipv6_set)
12655     {
12656       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12657       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12658     }
12659   else
12660     {
12661       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12662       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12663     }
12664   mp->encap_vrf_id = ntohl (encap_vrf_id);
12665   mp->decap_next_index = ntohl (decap_next_index);
12666   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12667   mp->vni = ntohl (vni);
12668   mp->is_add = is_add;
12669   mp->is_ipv6 = ipv6_set;
12670
12671   S (mp);
12672   W (ret);
12673   return ret;
12674 }
12675
12676 static void vl_api_geneve_tunnel_details_t_handler
12677   (vl_api_geneve_tunnel_details_t * mp)
12678 {
12679   vat_main_t *vam = &vat_main;
12680   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12681   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12682
12683   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12684          ntohl (mp->sw_if_index),
12685          format_ip46_address, &src, IP46_TYPE_ANY,
12686          format_ip46_address, &dst, IP46_TYPE_ANY,
12687          ntohl (mp->encap_vrf_id),
12688          ntohl (mp->decap_next_index), ntohl (mp->vni),
12689          ntohl (mp->mcast_sw_if_index));
12690 }
12691
12692 static void vl_api_geneve_tunnel_details_t_handler_json
12693   (vl_api_geneve_tunnel_details_t * mp)
12694 {
12695   vat_main_t *vam = &vat_main;
12696   vat_json_node_t *node = NULL;
12697
12698   if (VAT_JSON_ARRAY != vam->json_tree.type)
12699     {
12700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12701       vat_json_init_array (&vam->json_tree);
12702     }
12703   node = vat_json_array_add (&vam->json_tree);
12704
12705   vat_json_init_object (node);
12706   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12707   if (mp->is_ipv6)
12708     {
12709       struct in6_addr ip6;
12710
12711       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12712       vat_json_object_add_ip6 (node, "src_address", ip6);
12713       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12714       vat_json_object_add_ip6 (node, "dst_address", ip6);
12715     }
12716   else
12717     {
12718       struct in_addr ip4;
12719
12720       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12721       vat_json_object_add_ip4 (node, "src_address", ip4);
12722       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12723       vat_json_object_add_ip4 (node, "dst_address", ip4);
12724     }
12725   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12726   vat_json_object_add_uint (node, "decap_next_index",
12727                             ntohl (mp->decap_next_index));
12728   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12729   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12730   vat_json_object_add_uint (node, "mcast_sw_if_index",
12731                             ntohl (mp->mcast_sw_if_index));
12732 }
12733
12734 static int
12735 api_geneve_tunnel_dump (vat_main_t * vam)
12736 {
12737   unformat_input_t *i = vam->input;
12738   vl_api_geneve_tunnel_dump_t *mp;
12739   vl_api_control_ping_t *mp_ping;
12740   u32 sw_if_index;
12741   u8 sw_if_index_set = 0;
12742   int ret;
12743
12744   /* Parse args required to build the message */
12745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12746     {
12747       if (unformat (i, "sw_if_index %d", &sw_if_index))
12748         sw_if_index_set = 1;
12749       else
12750         break;
12751     }
12752
12753   if (sw_if_index_set == 0)
12754     {
12755       sw_if_index = ~0;
12756     }
12757
12758   if (!vam->json_output)
12759     {
12760       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12761              "sw_if_index", "local_address", "remote_address",
12762              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12763     }
12764
12765   /* Get list of geneve-tunnel interfaces */
12766   M (GENEVE_TUNNEL_DUMP, mp);
12767
12768   mp->sw_if_index = htonl (sw_if_index);
12769
12770   S (mp);
12771
12772   /* Use a control ping for synchronization */
12773   M (CONTROL_PING, mp_ping);
12774   S (mp_ping);
12775
12776   W (ret);
12777   return ret;
12778 }
12779
12780 static int
12781 api_gre_add_del_tunnel (vat_main_t * vam)
12782 {
12783   unformat_input_t *line_input = vam->input;
12784   vl_api_gre_add_del_tunnel_t *mp;
12785   ip4_address_t src4, dst4;
12786   ip6_address_t src6, dst6;
12787   u8 is_add = 1;
12788   u8 ipv4_set = 0;
12789   u8 ipv6_set = 0;
12790   u8 teb = 0;
12791   u8 src_set = 0;
12792   u8 dst_set = 0;
12793   u32 outer_fib_id = 0;
12794   int ret;
12795
12796   memset (&src4, 0, sizeof src4);
12797   memset (&dst4, 0, sizeof dst4);
12798   memset (&src6, 0, sizeof src6);
12799   memset (&dst6, 0, sizeof dst6);
12800
12801   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12802     {
12803       if (unformat (line_input, "del"))
12804         is_add = 0;
12805       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12806         {
12807           src_set = 1;
12808           ipv4_set = 1;
12809         }
12810       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12811         {
12812           dst_set = 1;
12813           ipv4_set = 1;
12814         }
12815       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12816         {
12817           src_set = 1;
12818           ipv6_set = 1;
12819         }
12820       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12821         {
12822           dst_set = 1;
12823           ipv6_set = 1;
12824         }
12825       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12826         ;
12827       else if (unformat (line_input, "teb"))
12828         teb = 1;
12829       else
12830         {
12831           errmsg ("parse error '%U'", format_unformat_error, line_input);
12832           return -99;
12833         }
12834     }
12835
12836   if (src_set == 0)
12837     {
12838       errmsg ("tunnel src address not specified");
12839       return -99;
12840     }
12841   if (dst_set == 0)
12842     {
12843       errmsg ("tunnel dst address not specified");
12844       return -99;
12845     }
12846   if (ipv4_set && ipv6_set)
12847     {
12848       errmsg ("both IPv4 and IPv6 addresses specified");
12849       return -99;
12850     }
12851
12852
12853   M (GRE_ADD_DEL_TUNNEL, mp);
12854
12855   if (ipv4_set)
12856     {
12857       clib_memcpy (&mp->src_address, &src4, 4);
12858       clib_memcpy (&mp->dst_address, &dst4, 4);
12859     }
12860   else
12861     {
12862       clib_memcpy (&mp->src_address, &src6, 16);
12863       clib_memcpy (&mp->dst_address, &dst6, 16);
12864     }
12865   mp->outer_fib_id = ntohl (outer_fib_id);
12866   mp->is_add = is_add;
12867   mp->teb = teb;
12868   mp->is_ipv6 = ipv6_set;
12869
12870   S (mp);
12871   W (ret);
12872   return ret;
12873 }
12874
12875 static void vl_api_gre_tunnel_details_t_handler
12876   (vl_api_gre_tunnel_details_t * mp)
12877 {
12878   vat_main_t *vam = &vat_main;
12879   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12880   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12881
12882   print (vam->ofp, "%11d%24U%24U%6d%14d",
12883          ntohl (mp->sw_if_index),
12884          format_ip46_address, &src, IP46_TYPE_ANY,
12885          format_ip46_address, &dst, IP46_TYPE_ANY,
12886          mp->teb, ntohl (mp->outer_fib_id));
12887 }
12888
12889 static void vl_api_gre_tunnel_details_t_handler_json
12890   (vl_api_gre_tunnel_details_t * mp)
12891 {
12892   vat_main_t *vam = &vat_main;
12893   vat_json_node_t *node = NULL;
12894   struct in_addr ip4;
12895   struct in6_addr ip6;
12896
12897   if (VAT_JSON_ARRAY != vam->json_tree.type)
12898     {
12899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12900       vat_json_init_array (&vam->json_tree);
12901     }
12902   node = vat_json_array_add (&vam->json_tree);
12903
12904   vat_json_init_object (node);
12905   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12906   if (!mp->is_ipv6)
12907     {
12908       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12909       vat_json_object_add_ip4 (node, "src_address", ip4);
12910       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12911       vat_json_object_add_ip4 (node, "dst_address", ip4);
12912     }
12913   else
12914     {
12915       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12916       vat_json_object_add_ip6 (node, "src_address", ip6);
12917       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12918       vat_json_object_add_ip6 (node, "dst_address", ip6);
12919     }
12920   vat_json_object_add_uint (node, "teb", mp->teb);
12921   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12922   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12923 }
12924
12925 static int
12926 api_gre_tunnel_dump (vat_main_t * vam)
12927 {
12928   unformat_input_t *i = vam->input;
12929   vl_api_gre_tunnel_dump_t *mp;
12930   vl_api_control_ping_t *mp_ping;
12931   u32 sw_if_index;
12932   u8 sw_if_index_set = 0;
12933   int ret;
12934
12935   /* Parse args required to build the message */
12936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12937     {
12938       if (unformat (i, "sw_if_index %d", &sw_if_index))
12939         sw_if_index_set = 1;
12940       else
12941         break;
12942     }
12943
12944   if (sw_if_index_set == 0)
12945     {
12946       sw_if_index = ~0;
12947     }
12948
12949   if (!vam->json_output)
12950     {
12951       print (vam->ofp, "%11s%24s%24s%6s%14s",
12952              "sw_if_index", "src_address", "dst_address", "teb",
12953              "outer_fib_id");
12954     }
12955
12956   /* Get list of gre-tunnel interfaces */
12957   M (GRE_TUNNEL_DUMP, mp);
12958
12959   mp->sw_if_index = htonl (sw_if_index);
12960
12961   S (mp);
12962
12963   /* Use a control ping for synchronization */
12964   MPING (CONTROL_PING, mp_ping);
12965   S (mp_ping);
12966
12967   W (ret);
12968   return ret;
12969 }
12970
12971 static int
12972 api_l2_fib_clear_table (vat_main_t * vam)
12973 {
12974 //  unformat_input_t * i = vam->input;
12975   vl_api_l2_fib_clear_table_t *mp;
12976   int ret;
12977
12978   M (L2_FIB_CLEAR_TABLE, mp);
12979
12980   S (mp);
12981   W (ret);
12982   return ret;
12983 }
12984
12985 static int
12986 api_l2_interface_efp_filter (vat_main_t * vam)
12987 {
12988   unformat_input_t *i = vam->input;
12989   vl_api_l2_interface_efp_filter_t *mp;
12990   u32 sw_if_index;
12991   u8 enable = 1;
12992   u8 sw_if_index_set = 0;
12993   int ret;
12994
12995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12996     {
12997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12998         sw_if_index_set = 1;
12999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13000         sw_if_index_set = 1;
13001       else if (unformat (i, "enable"))
13002         enable = 1;
13003       else if (unformat (i, "disable"))
13004         enable = 0;
13005       else
13006         {
13007           clib_warning ("parse error '%U'", format_unformat_error, i);
13008           return -99;
13009         }
13010     }
13011
13012   if (sw_if_index_set == 0)
13013     {
13014       errmsg ("missing sw_if_index");
13015       return -99;
13016     }
13017
13018   M (L2_INTERFACE_EFP_FILTER, mp);
13019
13020   mp->sw_if_index = ntohl (sw_if_index);
13021   mp->enable_disable = enable;
13022
13023   S (mp);
13024   W (ret);
13025   return ret;
13026 }
13027
13028 #define foreach_vtr_op                          \
13029 _("disable",  L2_VTR_DISABLED)                  \
13030 _("push-1",  L2_VTR_PUSH_1)                     \
13031 _("push-2",  L2_VTR_PUSH_2)                     \
13032 _("pop-1",  L2_VTR_POP_1)                       \
13033 _("pop-2",  L2_VTR_POP_2)                       \
13034 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13035 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13036 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13037 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13038
13039 static int
13040 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13041 {
13042   unformat_input_t *i = vam->input;
13043   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13044   u32 sw_if_index;
13045   u8 sw_if_index_set = 0;
13046   u8 vtr_op_set = 0;
13047   u32 vtr_op = 0;
13048   u32 push_dot1q = 1;
13049   u32 tag1 = ~0;
13050   u32 tag2 = ~0;
13051   int ret;
13052
13053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13054     {
13055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13056         sw_if_index_set = 1;
13057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13058         sw_if_index_set = 1;
13059       else if (unformat (i, "vtr_op %d", &vtr_op))
13060         vtr_op_set = 1;
13061 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13062       foreach_vtr_op
13063 #undef _
13064         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13065         ;
13066       else if (unformat (i, "tag1 %d", &tag1))
13067         ;
13068       else if (unformat (i, "tag2 %d", &tag2))
13069         ;
13070       else
13071         {
13072           clib_warning ("parse error '%U'", format_unformat_error, i);
13073           return -99;
13074         }
13075     }
13076
13077   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13078     {
13079       errmsg ("missing vtr operation or sw_if_index");
13080       return -99;
13081     }
13082
13083   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13084   mp->sw_if_index = ntohl (sw_if_index);
13085   mp->vtr_op = ntohl (vtr_op);
13086   mp->push_dot1q = ntohl (push_dot1q);
13087   mp->tag1 = ntohl (tag1);
13088   mp->tag2 = ntohl (tag2);
13089
13090   S (mp);
13091   W (ret);
13092   return ret;
13093 }
13094
13095 static int
13096 api_create_vhost_user_if (vat_main_t * vam)
13097 {
13098   unformat_input_t *i = vam->input;
13099   vl_api_create_vhost_user_if_t *mp;
13100   u8 *file_name;
13101   u8 is_server = 0;
13102   u8 file_name_set = 0;
13103   u32 custom_dev_instance = ~0;
13104   u8 hwaddr[6];
13105   u8 use_custom_mac = 0;
13106   u8 *tag = 0;
13107   int ret;
13108
13109   /* Shut up coverity */
13110   memset (hwaddr, 0, sizeof (hwaddr));
13111
13112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13113     {
13114       if (unformat (i, "socket %s", &file_name))
13115         {
13116           file_name_set = 1;
13117         }
13118       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13119         ;
13120       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13121         use_custom_mac = 1;
13122       else if (unformat (i, "server"))
13123         is_server = 1;
13124       else if (unformat (i, "tag %s", &tag))
13125         ;
13126       else
13127         break;
13128     }
13129
13130   if (file_name_set == 0)
13131     {
13132       errmsg ("missing socket file name");
13133       return -99;
13134     }
13135
13136   if (vec_len (file_name) > 255)
13137     {
13138       errmsg ("socket file name too long");
13139       return -99;
13140     }
13141   vec_add1 (file_name, 0);
13142
13143   M (CREATE_VHOST_USER_IF, mp);
13144
13145   mp->is_server = is_server;
13146   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13147   vec_free (file_name);
13148   if (custom_dev_instance != ~0)
13149     {
13150       mp->renumber = 1;
13151       mp->custom_dev_instance = ntohl (custom_dev_instance);
13152     }
13153   mp->use_custom_mac = use_custom_mac;
13154   clib_memcpy (mp->mac_address, hwaddr, 6);
13155   if (tag)
13156     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13157   vec_free (tag);
13158
13159   S (mp);
13160   W (ret);
13161   return ret;
13162 }
13163
13164 static int
13165 api_modify_vhost_user_if (vat_main_t * vam)
13166 {
13167   unformat_input_t *i = vam->input;
13168   vl_api_modify_vhost_user_if_t *mp;
13169   u8 *file_name;
13170   u8 is_server = 0;
13171   u8 file_name_set = 0;
13172   u32 custom_dev_instance = ~0;
13173   u8 sw_if_index_set = 0;
13174   u32 sw_if_index = (u32) ~ 0;
13175   int ret;
13176
13177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13178     {
13179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13180         sw_if_index_set = 1;
13181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13182         sw_if_index_set = 1;
13183       else if (unformat (i, "socket %s", &file_name))
13184         {
13185           file_name_set = 1;
13186         }
13187       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13188         ;
13189       else if (unformat (i, "server"))
13190         is_server = 1;
13191       else
13192         break;
13193     }
13194
13195   if (sw_if_index_set == 0)
13196     {
13197       errmsg ("missing sw_if_index or interface name");
13198       return -99;
13199     }
13200
13201   if (file_name_set == 0)
13202     {
13203       errmsg ("missing socket file name");
13204       return -99;
13205     }
13206
13207   if (vec_len (file_name) > 255)
13208     {
13209       errmsg ("socket file name too long");
13210       return -99;
13211     }
13212   vec_add1 (file_name, 0);
13213
13214   M (MODIFY_VHOST_USER_IF, mp);
13215
13216   mp->sw_if_index = ntohl (sw_if_index);
13217   mp->is_server = is_server;
13218   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13219   vec_free (file_name);
13220   if (custom_dev_instance != ~0)
13221     {
13222       mp->renumber = 1;
13223       mp->custom_dev_instance = ntohl (custom_dev_instance);
13224     }
13225
13226   S (mp);
13227   W (ret);
13228   return ret;
13229 }
13230
13231 static int
13232 api_delete_vhost_user_if (vat_main_t * vam)
13233 {
13234   unformat_input_t *i = vam->input;
13235   vl_api_delete_vhost_user_if_t *mp;
13236   u32 sw_if_index = ~0;
13237   u8 sw_if_index_set = 0;
13238   int ret;
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13243         sw_if_index_set = 1;
13244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13245         sw_if_index_set = 1;
13246       else
13247         break;
13248     }
13249
13250   if (sw_if_index_set == 0)
13251     {
13252       errmsg ("missing sw_if_index or interface name");
13253       return -99;
13254     }
13255
13256
13257   M (DELETE_VHOST_USER_IF, mp);
13258
13259   mp->sw_if_index = ntohl (sw_if_index);
13260
13261   S (mp);
13262   W (ret);
13263   return ret;
13264 }
13265
13266 static void vl_api_sw_interface_vhost_user_details_t_handler
13267   (vl_api_sw_interface_vhost_user_details_t * mp)
13268 {
13269   vat_main_t *vam = &vat_main;
13270
13271   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13272          (char *) mp->interface_name,
13273          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13274          clib_net_to_host_u64 (mp->features), mp->is_server,
13275          ntohl (mp->num_regions), (char *) mp->sock_filename);
13276   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13277 }
13278
13279 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13280   (vl_api_sw_interface_vhost_user_details_t * mp)
13281 {
13282   vat_main_t *vam = &vat_main;
13283   vat_json_node_t *node = NULL;
13284
13285   if (VAT_JSON_ARRAY != vam->json_tree.type)
13286     {
13287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13288       vat_json_init_array (&vam->json_tree);
13289     }
13290   node = vat_json_array_add (&vam->json_tree);
13291
13292   vat_json_init_object (node);
13293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13294   vat_json_object_add_string_copy (node, "interface_name",
13295                                    mp->interface_name);
13296   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13297                             ntohl (mp->virtio_net_hdr_sz));
13298   vat_json_object_add_uint (node, "features",
13299                             clib_net_to_host_u64 (mp->features));
13300   vat_json_object_add_uint (node, "is_server", mp->is_server);
13301   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13302   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13303   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13304 }
13305
13306 static int
13307 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13308 {
13309   vl_api_sw_interface_vhost_user_dump_t *mp;
13310   vl_api_control_ping_t *mp_ping;
13311   int ret;
13312   print (vam->ofp,
13313          "Interface name            idx hdr_sz features server regions filename");
13314
13315   /* Get list of vhost-user interfaces */
13316   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13317   S (mp);
13318
13319   /* Use a control ping for synchronization */
13320   MPING (CONTROL_PING, mp_ping);
13321   S (mp_ping);
13322
13323   W (ret);
13324   return ret;
13325 }
13326
13327 static int
13328 api_show_version (vat_main_t * vam)
13329 {
13330   vl_api_show_version_t *mp;
13331   int ret;
13332
13333   M (SHOW_VERSION, mp);
13334
13335   S (mp);
13336   W (ret);
13337   return ret;
13338 }
13339
13340
13341 static int
13342 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13343 {
13344   unformat_input_t *line_input = vam->input;
13345   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13346   ip4_address_t local4, remote4;
13347   ip6_address_t local6, remote6;
13348   u8 is_add = 1;
13349   u8 ipv4_set = 0, ipv6_set = 0;
13350   u8 local_set = 0;
13351   u8 remote_set = 0;
13352   u8 grp_set = 0;
13353   u32 mcast_sw_if_index = ~0;
13354   u32 encap_vrf_id = 0;
13355   u32 decap_vrf_id = 0;
13356   u8 protocol = ~0;
13357   u32 vni;
13358   u8 vni_set = 0;
13359   int ret;
13360
13361   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13362   memset (&local4, 0, sizeof local4);
13363   memset (&remote4, 0, sizeof remote4);
13364   memset (&local6, 0, sizeof local6);
13365   memset (&remote6, 0, sizeof remote6);
13366
13367   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13368     {
13369       if (unformat (line_input, "del"))
13370         is_add = 0;
13371       else if (unformat (line_input, "local %U",
13372                          unformat_ip4_address, &local4))
13373         {
13374           local_set = 1;
13375           ipv4_set = 1;
13376         }
13377       else if (unformat (line_input, "remote %U",
13378                          unformat_ip4_address, &remote4))
13379         {
13380           remote_set = 1;
13381           ipv4_set = 1;
13382         }
13383       else if (unformat (line_input, "local %U",
13384                          unformat_ip6_address, &local6))
13385         {
13386           local_set = 1;
13387           ipv6_set = 1;
13388         }
13389       else if (unformat (line_input, "remote %U",
13390                          unformat_ip6_address, &remote6))
13391         {
13392           remote_set = 1;
13393           ipv6_set = 1;
13394         }
13395       else if (unformat (line_input, "group %U %U",
13396                          unformat_ip4_address, &remote4,
13397                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13398         {
13399           grp_set = remote_set = 1;
13400           ipv4_set = 1;
13401         }
13402       else if (unformat (line_input, "group %U",
13403                          unformat_ip4_address, &remote4))
13404         {
13405           grp_set = remote_set = 1;
13406           ipv4_set = 1;
13407         }
13408       else if (unformat (line_input, "group %U %U",
13409                          unformat_ip6_address, &remote6,
13410                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13411         {
13412           grp_set = remote_set = 1;
13413           ipv6_set = 1;
13414         }
13415       else if (unformat (line_input, "group %U",
13416                          unformat_ip6_address, &remote6))
13417         {
13418           grp_set = remote_set = 1;
13419           ipv6_set = 1;
13420         }
13421       else
13422         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13423         ;
13424       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13425         ;
13426       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13427         ;
13428       else if (unformat (line_input, "vni %d", &vni))
13429         vni_set = 1;
13430       else if (unformat (line_input, "next-ip4"))
13431         protocol = 1;
13432       else if (unformat (line_input, "next-ip6"))
13433         protocol = 2;
13434       else if (unformat (line_input, "next-ethernet"))
13435         protocol = 3;
13436       else if (unformat (line_input, "next-nsh"))
13437         protocol = 4;
13438       else
13439         {
13440           errmsg ("parse error '%U'", format_unformat_error, line_input);
13441           return -99;
13442         }
13443     }
13444
13445   if (local_set == 0)
13446     {
13447       errmsg ("tunnel local address not specified");
13448       return -99;
13449     }
13450   if (remote_set == 0)
13451     {
13452       errmsg ("tunnel remote address not specified");
13453       return -99;
13454     }
13455   if (grp_set && mcast_sw_if_index == ~0)
13456     {
13457       errmsg ("tunnel nonexistent multicast device");
13458       return -99;
13459     }
13460   if (ipv4_set && ipv6_set)
13461     {
13462       errmsg ("both IPv4 and IPv6 addresses specified");
13463       return -99;
13464     }
13465
13466   if (vni_set == 0)
13467     {
13468       errmsg ("vni not specified");
13469       return -99;
13470     }
13471
13472   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13473
13474
13475   if (ipv6_set)
13476     {
13477       clib_memcpy (&mp->local, &local6, sizeof (local6));
13478       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13479     }
13480   else
13481     {
13482       clib_memcpy (&mp->local, &local4, sizeof (local4));
13483       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13484     }
13485
13486   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13487   mp->encap_vrf_id = ntohl (encap_vrf_id);
13488   mp->decap_vrf_id = ntohl (decap_vrf_id);
13489   mp->protocol = protocol;
13490   mp->vni = ntohl (vni);
13491   mp->is_add = is_add;
13492   mp->is_ipv6 = ipv6_set;
13493
13494   S (mp);
13495   W (ret);
13496   return ret;
13497 }
13498
13499 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13500   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13501 {
13502   vat_main_t *vam = &vat_main;
13503   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13504   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13505
13506   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13507          ntohl (mp->sw_if_index),
13508          format_ip46_address, &local, IP46_TYPE_ANY,
13509          format_ip46_address, &remote, IP46_TYPE_ANY,
13510          ntohl (mp->vni), mp->protocol,
13511          ntohl (mp->mcast_sw_if_index),
13512          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13513 }
13514
13515
13516 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13517   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13518 {
13519   vat_main_t *vam = &vat_main;
13520   vat_json_node_t *node = NULL;
13521   struct in_addr ip4;
13522   struct in6_addr ip6;
13523
13524   if (VAT_JSON_ARRAY != vam->json_tree.type)
13525     {
13526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13527       vat_json_init_array (&vam->json_tree);
13528     }
13529   node = vat_json_array_add (&vam->json_tree);
13530
13531   vat_json_init_object (node);
13532   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13533   if (mp->is_ipv6)
13534     {
13535       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13536       vat_json_object_add_ip6 (node, "local", ip6);
13537       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13538       vat_json_object_add_ip6 (node, "remote", ip6);
13539     }
13540   else
13541     {
13542       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13543       vat_json_object_add_ip4 (node, "local", ip4);
13544       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13545       vat_json_object_add_ip4 (node, "remote", ip4);
13546     }
13547   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13548   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13549   vat_json_object_add_uint (node, "mcast_sw_if_index",
13550                             ntohl (mp->mcast_sw_if_index));
13551   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13552   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13553   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13554 }
13555
13556 static int
13557 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13558 {
13559   unformat_input_t *i = vam->input;
13560   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13561   vl_api_control_ping_t *mp_ping;
13562   u32 sw_if_index;
13563   u8 sw_if_index_set = 0;
13564   int ret;
13565
13566   /* Parse args required to build the message */
13567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13568     {
13569       if (unformat (i, "sw_if_index %d", &sw_if_index))
13570         sw_if_index_set = 1;
13571       else
13572         break;
13573     }
13574
13575   if (sw_if_index_set == 0)
13576     {
13577       sw_if_index = ~0;
13578     }
13579
13580   if (!vam->json_output)
13581     {
13582       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13583              "sw_if_index", "local", "remote", "vni",
13584              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13585     }
13586
13587   /* Get list of vxlan-tunnel interfaces */
13588   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13589
13590   mp->sw_if_index = htonl (sw_if_index);
13591
13592   S (mp);
13593
13594   /* Use a control ping for synchronization */
13595   MPING (CONTROL_PING, mp_ping);
13596   S (mp_ping);
13597
13598   W (ret);
13599   return ret;
13600 }
13601
13602 static void vl_api_l2_fib_table_details_t_handler
13603   (vl_api_l2_fib_table_details_t * mp)
13604 {
13605   vat_main_t *vam = &vat_main;
13606
13607   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13608          "       %d       %d     %d",
13609          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13610          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13611          mp->bvi_mac);
13612 }
13613
13614 static void vl_api_l2_fib_table_details_t_handler_json
13615   (vl_api_l2_fib_table_details_t * mp)
13616 {
13617   vat_main_t *vam = &vat_main;
13618   vat_json_node_t *node = NULL;
13619
13620   if (VAT_JSON_ARRAY != vam->json_tree.type)
13621     {
13622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13623       vat_json_init_array (&vam->json_tree);
13624     }
13625   node = vat_json_array_add (&vam->json_tree);
13626
13627   vat_json_init_object (node);
13628   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13629   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13630   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13631   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13632   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13633   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13634 }
13635
13636 static int
13637 api_l2_fib_table_dump (vat_main_t * vam)
13638 {
13639   unformat_input_t *i = vam->input;
13640   vl_api_l2_fib_table_dump_t *mp;
13641   vl_api_control_ping_t *mp_ping;
13642   u32 bd_id;
13643   u8 bd_id_set = 0;
13644   int ret;
13645
13646   /* Parse args required to build the message */
13647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13648     {
13649       if (unformat (i, "bd_id %d", &bd_id))
13650         bd_id_set = 1;
13651       else
13652         break;
13653     }
13654
13655   if (bd_id_set == 0)
13656     {
13657       errmsg ("missing bridge domain");
13658       return -99;
13659     }
13660
13661   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13662
13663   /* Get list of l2 fib entries */
13664   M (L2_FIB_TABLE_DUMP, mp);
13665
13666   mp->bd_id = ntohl (bd_id);
13667   S (mp);
13668
13669   /* Use a control ping for synchronization */
13670   MPING (CONTROL_PING, mp_ping);
13671   S (mp_ping);
13672
13673   W (ret);
13674   return ret;
13675 }
13676
13677
13678 static int
13679 api_interface_name_renumber (vat_main_t * vam)
13680 {
13681   unformat_input_t *line_input = vam->input;
13682   vl_api_interface_name_renumber_t *mp;
13683   u32 sw_if_index = ~0;
13684   u32 new_show_dev_instance = ~0;
13685   int ret;
13686
13687   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13688     {
13689       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13690                     &sw_if_index))
13691         ;
13692       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13693         ;
13694       else if (unformat (line_input, "new_show_dev_instance %d",
13695                          &new_show_dev_instance))
13696         ;
13697       else
13698         break;
13699     }
13700
13701   if (sw_if_index == ~0)
13702     {
13703       errmsg ("missing interface name or sw_if_index");
13704       return -99;
13705     }
13706
13707   if (new_show_dev_instance == ~0)
13708     {
13709       errmsg ("missing new_show_dev_instance");
13710       return -99;
13711     }
13712
13713   M (INTERFACE_NAME_RENUMBER, mp);
13714
13715   mp->sw_if_index = ntohl (sw_if_index);
13716   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13717
13718   S (mp);
13719   W (ret);
13720   return ret;
13721 }
13722
13723 static int
13724 api_want_ip4_arp_events (vat_main_t * vam)
13725 {
13726   unformat_input_t *line_input = vam->input;
13727   vl_api_want_ip4_arp_events_t *mp;
13728   ip4_address_t address;
13729   int address_set = 0;
13730   u32 enable_disable = 1;
13731   int ret;
13732
13733   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13734     {
13735       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13736         address_set = 1;
13737       else if (unformat (line_input, "del"))
13738         enable_disable = 0;
13739       else
13740         break;
13741     }
13742
13743   if (address_set == 0)
13744     {
13745       errmsg ("missing addresses");
13746       return -99;
13747     }
13748
13749   M (WANT_IP4_ARP_EVENTS, mp);
13750   mp->enable_disable = enable_disable;
13751   mp->pid = htonl (getpid ());
13752   mp->address = address.as_u32;
13753
13754   S (mp);
13755   W (ret);
13756   return ret;
13757 }
13758
13759 static int
13760 api_want_ip6_nd_events (vat_main_t * vam)
13761 {
13762   unformat_input_t *line_input = vam->input;
13763   vl_api_want_ip6_nd_events_t *mp;
13764   ip6_address_t address;
13765   int address_set = 0;
13766   u32 enable_disable = 1;
13767   int ret;
13768
13769   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13770     {
13771       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13772         address_set = 1;
13773       else if (unformat (line_input, "del"))
13774         enable_disable = 0;
13775       else
13776         break;
13777     }
13778
13779   if (address_set == 0)
13780     {
13781       errmsg ("missing addresses");
13782       return -99;
13783     }
13784
13785   M (WANT_IP6_ND_EVENTS, mp);
13786   mp->enable_disable = enable_disable;
13787   mp->pid = htonl (getpid ());
13788   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13789
13790   S (mp);
13791   W (ret);
13792   return ret;
13793 }
13794
13795 static int
13796 api_want_l2_macs_events (vat_main_t * vam)
13797 {
13798   unformat_input_t *line_input = vam->input;
13799   vl_api_want_l2_macs_events_t *mp;
13800   u8 enable_disable = 1;
13801   u32 scan_delay = 0;
13802   u32 max_macs_in_event = 0;
13803   u32 learn_limit = 0;
13804   int ret;
13805
13806   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13807     {
13808       if (unformat (line_input, "learn-limit %d", &learn_limit))
13809         ;
13810       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13811         ;
13812       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13813         ;
13814       else if (unformat (line_input, "disable"))
13815         enable_disable = 0;
13816       else
13817         break;
13818     }
13819
13820   M (WANT_L2_MACS_EVENTS, mp);
13821   mp->enable_disable = enable_disable;
13822   mp->pid = htonl (getpid ());
13823   mp->learn_limit = htonl (learn_limit);
13824   mp->scan_delay = (u8) scan_delay;
13825   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13826   S (mp);
13827   W (ret);
13828   return ret;
13829 }
13830
13831 static int
13832 api_input_acl_set_interface (vat_main_t * vam)
13833 {
13834   unformat_input_t *i = vam->input;
13835   vl_api_input_acl_set_interface_t *mp;
13836   u32 sw_if_index;
13837   int sw_if_index_set;
13838   u32 ip4_table_index = ~0;
13839   u32 ip6_table_index = ~0;
13840   u32 l2_table_index = ~0;
13841   u8 is_add = 1;
13842   int ret;
13843
13844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13847         sw_if_index_set = 1;
13848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13849         sw_if_index_set = 1;
13850       else if (unformat (i, "del"))
13851         is_add = 0;
13852       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13853         ;
13854       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13855         ;
13856       else if (unformat (i, "l2-table %d", &l2_table_index))
13857         ;
13858       else
13859         {
13860           clib_warning ("parse error '%U'", format_unformat_error, i);
13861           return -99;
13862         }
13863     }
13864
13865   if (sw_if_index_set == 0)
13866     {
13867       errmsg ("missing interface name or sw_if_index");
13868       return -99;
13869     }
13870
13871   M (INPUT_ACL_SET_INTERFACE, mp);
13872
13873   mp->sw_if_index = ntohl (sw_if_index);
13874   mp->ip4_table_index = ntohl (ip4_table_index);
13875   mp->ip6_table_index = ntohl (ip6_table_index);
13876   mp->l2_table_index = ntohl (l2_table_index);
13877   mp->is_add = is_add;
13878
13879   S (mp);
13880   W (ret);
13881   return ret;
13882 }
13883
13884 static int
13885 api_ip_address_dump (vat_main_t * vam)
13886 {
13887   unformat_input_t *i = vam->input;
13888   vl_api_ip_address_dump_t *mp;
13889   vl_api_control_ping_t *mp_ping;
13890   u32 sw_if_index = ~0;
13891   u8 sw_if_index_set = 0;
13892   u8 ipv4_set = 0;
13893   u8 ipv6_set = 0;
13894   int ret;
13895
13896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13897     {
13898       if (unformat (i, "sw_if_index %d", &sw_if_index))
13899         sw_if_index_set = 1;
13900       else
13901         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13902         sw_if_index_set = 1;
13903       else if (unformat (i, "ipv4"))
13904         ipv4_set = 1;
13905       else if (unformat (i, "ipv6"))
13906         ipv6_set = 1;
13907       else
13908         break;
13909     }
13910
13911   if (ipv4_set && ipv6_set)
13912     {
13913       errmsg ("ipv4 and ipv6 flags cannot be both set");
13914       return -99;
13915     }
13916
13917   if ((!ipv4_set) && (!ipv6_set))
13918     {
13919       errmsg ("no ipv4 nor ipv6 flag set");
13920       return -99;
13921     }
13922
13923   if (sw_if_index_set == 0)
13924     {
13925       errmsg ("missing interface name or sw_if_index");
13926       return -99;
13927     }
13928
13929   vam->current_sw_if_index = sw_if_index;
13930   vam->is_ipv6 = ipv6_set;
13931
13932   M (IP_ADDRESS_DUMP, mp);
13933   mp->sw_if_index = ntohl (sw_if_index);
13934   mp->is_ipv6 = ipv6_set;
13935   S (mp);
13936
13937   /* Use a control ping for synchronization */
13938   MPING (CONTROL_PING, mp_ping);
13939   S (mp_ping);
13940
13941   W (ret);
13942   return ret;
13943 }
13944
13945 static int
13946 api_ip_dump (vat_main_t * vam)
13947 {
13948   vl_api_ip_dump_t *mp;
13949   vl_api_control_ping_t *mp_ping;
13950   unformat_input_t *in = vam->input;
13951   int ipv4_set = 0;
13952   int ipv6_set = 0;
13953   int is_ipv6;
13954   int i;
13955   int ret;
13956
13957   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (in, "ipv4"))
13960         ipv4_set = 1;
13961       else if (unformat (in, "ipv6"))
13962         ipv6_set = 1;
13963       else
13964         break;
13965     }
13966
13967   if (ipv4_set && ipv6_set)
13968     {
13969       errmsg ("ipv4 and ipv6 flags cannot be both set");
13970       return -99;
13971     }
13972
13973   if ((!ipv4_set) && (!ipv6_set))
13974     {
13975       errmsg ("no ipv4 nor ipv6 flag set");
13976       return -99;
13977     }
13978
13979   is_ipv6 = ipv6_set;
13980   vam->is_ipv6 = is_ipv6;
13981
13982   /* free old data */
13983   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13984     {
13985       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13986     }
13987   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13988
13989   M (IP_DUMP, mp);
13990   mp->is_ipv6 = ipv6_set;
13991   S (mp);
13992
13993   /* Use a control ping for synchronization */
13994   MPING (CONTROL_PING, mp_ping);
13995   S (mp_ping);
13996
13997   W (ret);
13998   return ret;
13999 }
14000
14001 static int
14002 api_ipsec_spd_add_del (vat_main_t * vam)
14003 {
14004   unformat_input_t *i = vam->input;
14005   vl_api_ipsec_spd_add_del_t *mp;
14006   u32 spd_id = ~0;
14007   u8 is_add = 1;
14008   int ret;
14009
14010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14011     {
14012       if (unformat (i, "spd_id %d", &spd_id))
14013         ;
14014       else if (unformat (i, "del"))
14015         is_add = 0;
14016       else
14017         {
14018           clib_warning ("parse error '%U'", format_unformat_error, i);
14019           return -99;
14020         }
14021     }
14022   if (spd_id == ~0)
14023     {
14024       errmsg ("spd_id must be set");
14025       return -99;
14026     }
14027
14028   M (IPSEC_SPD_ADD_DEL, mp);
14029
14030   mp->spd_id = ntohl (spd_id);
14031   mp->is_add = is_add;
14032
14033   S (mp);
14034   W (ret);
14035   return ret;
14036 }
14037
14038 static int
14039 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14040 {
14041   unformat_input_t *i = vam->input;
14042   vl_api_ipsec_interface_add_del_spd_t *mp;
14043   u32 sw_if_index;
14044   u8 sw_if_index_set = 0;
14045   u32 spd_id = (u32) ~ 0;
14046   u8 is_add = 1;
14047   int ret;
14048
14049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14050     {
14051       if (unformat (i, "del"))
14052         is_add = 0;
14053       else if (unformat (i, "spd_id %d", &spd_id))
14054         ;
14055       else
14056         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14057         sw_if_index_set = 1;
14058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14059         sw_if_index_set = 1;
14060       else
14061         {
14062           clib_warning ("parse error '%U'", format_unformat_error, i);
14063           return -99;
14064         }
14065
14066     }
14067
14068   if (spd_id == (u32) ~ 0)
14069     {
14070       errmsg ("spd_id must be set");
14071       return -99;
14072     }
14073
14074   if (sw_if_index_set == 0)
14075     {
14076       errmsg ("missing interface name or sw_if_index");
14077       return -99;
14078     }
14079
14080   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14081
14082   mp->spd_id = ntohl (spd_id);
14083   mp->sw_if_index = ntohl (sw_if_index);
14084   mp->is_add = is_add;
14085
14086   S (mp);
14087   W (ret);
14088   return ret;
14089 }
14090
14091 static int
14092 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14093 {
14094   unformat_input_t *i = vam->input;
14095   vl_api_ipsec_spd_add_del_entry_t *mp;
14096   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14097   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14098   i32 priority = 0;
14099   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14100   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14101   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14102   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14103   int ret;
14104
14105   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14106   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14107   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14108   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14109   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14110   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14111
14112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (i, "del"))
14115         is_add = 0;
14116       if (unformat (i, "outbound"))
14117         is_outbound = 1;
14118       if (unformat (i, "inbound"))
14119         is_outbound = 0;
14120       else if (unformat (i, "spd_id %d", &spd_id))
14121         ;
14122       else if (unformat (i, "sa_id %d", &sa_id))
14123         ;
14124       else if (unformat (i, "priority %d", &priority))
14125         ;
14126       else if (unformat (i, "protocol %d", &protocol))
14127         ;
14128       else if (unformat (i, "lport_start %d", &lport_start))
14129         ;
14130       else if (unformat (i, "lport_stop %d", &lport_stop))
14131         ;
14132       else if (unformat (i, "rport_start %d", &rport_start))
14133         ;
14134       else if (unformat (i, "rport_stop %d", &rport_stop))
14135         ;
14136       else
14137         if (unformat
14138             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14139         {
14140           is_ipv6 = 0;
14141           is_ip_any = 0;
14142         }
14143       else
14144         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14145         {
14146           is_ipv6 = 0;
14147           is_ip_any = 0;
14148         }
14149       else
14150         if (unformat
14151             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14152         {
14153           is_ipv6 = 0;
14154           is_ip_any = 0;
14155         }
14156       else
14157         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14158         {
14159           is_ipv6 = 0;
14160           is_ip_any = 0;
14161         }
14162       else
14163         if (unformat
14164             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14165         {
14166           is_ipv6 = 1;
14167           is_ip_any = 0;
14168         }
14169       else
14170         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14171         {
14172           is_ipv6 = 1;
14173           is_ip_any = 0;
14174         }
14175       else
14176         if (unformat
14177             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14178         {
14179           is_ipv6 = 1;
14180           is_ip_any = 0;
14181         }
14182       else
14183         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14184         {
14185           is_ipv6 = 1;
14186           is_ip_any = 0;
14187         }
14188       else
14189         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14190         {
14191           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14192             {
14193               clib_warning ("unsupported action: 'resolve'");
14194               return -99;
14195             }
14196         }
14197       else
14198         {
14199           clib_warning ("parse error '%U'", format_unformat_error, i);
14200           return -99;
14201         }
14202
14203     }
14204
14205   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14206
14207   mp->spd_id = ntohl (spd_id);
14208   mp->priority = ntohl (priority);
14209   mp->is_outbound = is_outbound;
14210
14211   mp->is_ipv6 = is_ipv6;
14212   if (is_ipv6 || is_ip_any)
14213     {
14214       clib_memcpy (mp->remote_address_start, &raddr6_start,
14215                    sizeof (ip6_address_t));
14216       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14217                    sizeof (ip6_address_t));
14218       clib_memcpy (mp->local_address_start, &laddr6_start,
14219                    sizeof (ip6_address_t));
14220       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14221                    sizeof (ip6_address_t));
14222     }
14223   else
14224     {
14225       clib_memcpy (mp->remote_address_start, &raddr4_start,
14226                    sizeof (ip4_address_t));
14227       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14228                    sizeof (ip4_address_t));
14229       clib_memcpy (mp->local_address_start, &laddr4_start,
14230                    sizeof (ip4_address_t));
14231       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14232                    sizeof (ip4_address_t));
14233     }
14234   mp->protocol = (u8) protocol;
14235   mp->local_port_start = ntohs ((u16) lport_start);
14236   mp->local_port_stop = ntohs ((u16) lport_stop);
14237   mp->remote_port_start = ntohs ((u16) rport_start);
14238   mp->remote_port_stop = ntohs ((u16) rport_stop);
14239   mp->policy = (u8) policy;
14240   mp->sa_id = ntohl (sa_id);
14241   mp->is_add = is_add;
14242   mp->is_ip_any = is_ip_any;
14243   S (mp);
14244   W (ret);
14245   return ret;
14246 }
14247
14248 static int
14249 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14250 {
14251   unformat_input_t *i = vam->input;
14252   vl_api_ipsec_sad_add_del_entry_t *mp;
14253   u32 sad_id = 0, spi = 0;
14254   u8 *ck = 0, *ik = 0;
14255   u8 is_add = 1;
14256
14257   u8 protocol = IPSEC_PROTOCOL_AH;
14258   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14259   u32 crypto_alg = 0, integ_alg = 0;
14260   ip4_address_t tun_src4;
14261   ip4_address_t tun_dst4;
14262   ip6_address_t tun_src6;
14263   ip6_address_t tun_dst6;
14264   int ret;
14265
14266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14267     {
14268       if (unformat (i, "del"))
14269         is_add = 0;
14270       else if (unformat (i, "sad_id %d", &sad_id))
14271         ;
14272       else if (unformat (i, "spi %d", &spi))
14273         ;
14274       else if (unformat (i, "esp"))
14275         protocol = IPSEC_PROTOCOL_ESP;
14276       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14277         {
14278           is_tunnel = 1;
14279           is_tunnel_ipv6 = 0;
14280         }
14281       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14282         {
14283           is_tunnel = 1;
14284           is_tunnel_ipv6 = 0;
14285         }
14286       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14287         {
14288           is_tunnel = 1;
14289           is_tunnel_ipv6 = 1;
14290         }
14291       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14292         {
14293           is_tunnel = 1;
14294           is_tunnel_ipv6 = 1;
14295         }
14296       else
14297         if (unformat
14298             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14299         {
14300           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14301               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14302             {
14303               clib_warning ("unsupported crypto-alg: '%U'",
14304                             format_ipsec_crypto_alg, crypto_alg);
14305               return -99;
14306             }
14307         }
14308       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14309         ;
14310       else
14311         if (unformat
14312             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14313         {
14314           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14315               integ_alg >= IPSEC_INTEG_N_ALG)
14316             {
14317               clib_warning ("unsupported integ-alg: '%U'",
14318                             format_ipsec_integ_alg, integ_alg);
14319               return -99;
14320             }
14321         }
14322       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14323         ;
14324       else
14325         {
14326           clib_warning ("parse error '%U'", format_unformat_error, i);
14327           return -99;
14328         }
14329
14330     }
14331
14332   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14333
14334   mp->sad_id = ntohl (sad_id);
14335   mp->is_add = is_add;
14336   mp->protocol = protocol;
14337   mp->spi = ntohl (spi);
14338   mp->is_tunnel = is_tunnel;
14339   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14340   mp->crypto_algorithm = crypto_alg;
14341   mp->integrity_algorithm = integ_alg;
14342   mp->crypto_key_length = vec_len (ck);
14343   mp->integrity_key_length = vec_len (ik);
14344
14345   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14346     mp->crypto_key_length = sizeof (mp->crypto_key);
14347
14348   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14349     mp->integrity_key_length = sizeof (mp->integrity_key);
14350
14351   if (ck)
14352     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14353   if (ik)
14354     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14355
14356   if (is_tunnel)
14357     {
14358       if (is_tunnel_ipv6)
14359         {
14360           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14361                        sizeof (ip6_address_t));
14362           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14363                        sizeof (ip6_address_t));
14364         }
14365       else
14366         {
14367           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14368                        sizeof (ip4_address_t));
14369           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14370                        sizeof (ip4_address_t));
14371         }
14372     }
14373
14374   S (mp);
14375   W (ret);
14376   return ret;
14377 }
14378
14379 static int
14380 api_ipsec_sa_set_key (vat_main_t * vam)
14381 {
14382   unformat_input_t *i = vam->input;
14383   vl_api_ipsec_sa_set_key_t *mp;
14384   u32 sa_id;
14385   u8 *ck = 0, *ik = 0;
14386   int ret;
14387
14388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14389     {
14390       if (unformat (i, "sa_id %d", &sa_id))
14391         ;
14392       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14393         ;
14394       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14395         ;
14396       else
14397         {
14398           clib_warning ("parse error '%U'", format_unformat_error, i);
14399           return -99;
14400         }
14401     }
14402
14403   M (IPSEC_SA_SET_KEY, mp);
14404
14405   mp->sa_id = ntohl (sa_id);
14406   mp->crypto_key_length = vec_len (ck);
14407   mp->integrity_key_length = vec_len (ik);
14408
14409   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14410     mp->crypto_key_length = sizeof (mp->crypto_key);
14411
14412   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14413     mp->integrity_key_length = sizeof (mp->integrity_key);
14414
14415   if (ck)
14416     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14417   if (ik)
14418     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14419
14420   S (mp);
14421   W (ret);
14422   return ret;
14423 }
14424
14425 static int
14426 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14427 {
14428   unformat_input_t *i = vam->input;
14429   vl_api_ipsec_tunnel_if_add_del_t *mp;
14430   u32 local_spi = 0, remote_spi = 0;
14431   u32 crypto_alg = 0, integ_alg = 0;
14432   u8 *lck = NULL, *rck = NULL;
14433   u8 *lik = NULL, *rik = NULL;
14434   ip4_address_t local_ip = { {0} };
14435   ip4_address_t remote_ip = { {0} };
14436   u8 is_add = 1;
14437   u8 esn = 0;
14438   u8 anti_replay = 0;
14439   int ret;
14440
14441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14442     {
14443       if (unformat (i, "del"))
14444         is_add = 0;
14445       else if (unformat (i, "esn"))
14446         esn = 1;
14447       else if (unformat (i, "anti_replay"))
14448         anti_replay = 1;
14449       else if (unformat (i, "local_spi %d", &local_spi))
14450         ;
14451       else if (unformat (i, "remote_spi %d", &remote_spi))
14452         ;
14453       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14454         ;
14455       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14456         ;
14457       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14458         ;
14459       else
14460         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14461         ;
14462       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14463         ;
14464       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14465         ;
14466       else
14467         if (unformat
14468             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14469         {
14470           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14471               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14472             {
14473               errmsg ("unsupported crypto-alg: '%U'\n",
14474                       format_ipsec_crypto_alg, crypto_alg);
14475               return -99;
14476             }
14477         }
14478       else
14479         if (unformat
14480             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14481         {
14482           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14483               integ_alg >= IPSEC_INTEG_N_ALG)
14484             {
14485               errmsg ("unsupported integ-alg: '%U'\n",
14486                       format_ipsec_integ_alg, integ_alg);
14487               return -99;
14488             }
14489         }
14490       else
14491         {
14492           errmsg ("parse error '%U'\n", format_unformat_error, i);
14493           return -99;
14494         }
14495     }
14496
14497   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14498
14499   mp->is_add = is_add;
14500   mp->esn = esn;
14501   mp->anti_replay = anti_replay;
14502
14503   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14504   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14505
14506   mp->local_spi = htonl (local_spi);
14507   mp->remote_spi = htonl (remote_spi);
14508   mp->crypto_alg = (u8) crypto_alg;
14509
14510   mp->local_crypto_key_len = 0;
14511   if (lck)
14512     {
14513       mp->local_crypto_key_len = vec_len (lck);
14514       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14515         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14516       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14517     }
14518
14519   mp->remote_crypto_key_len = 0;
14520   if (rck)
14521     {
14522       mp->remote_crypto_key_len = vec_len (rck);
14523       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14524         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14525       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14526     }
14527
14528   mp->integ_alg = (u8) integ_alg;
14529
14530   mp->local_integ_key_len = 0;
14531   if (lik)
14532     {
14533       mp->local_integ_key_len = vec_len (lik);
14534       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14535         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14536       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14537     }
14538
14539   mp->remote_integ_key_len = 0;
14540   if (rik)
14541     {
14542       mp->remote_integ_key_len = vec_len (rik);
14543       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14544         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14545       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14546     }
14547
14548   S (mp);
14549   W (ret);
14550   return ret;
14551 }
14552
14553 static void
14554 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14555 {
14556   vat_main_t *vam = &vat_main;
14557
14558   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14559          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14560          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14561          "tunnel_src_addr %U tunnel_dst_addr %U "
14562          "salt %u seq_outbound %lu last_seq_inbound %lu "
14563          "replay_window %lu total_data_size %lu\n",
14564          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14565          mp->protocol,
14566          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14567          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14568          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14569          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14570          mp->tunnel_src_addr,
14571          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14572          mp->tunnel_dst_addr,
14573          ntohl (mp->salt),
14574          clib_net_to_host_u64 (mp->seq_outbound),
14575          clib_net_to_host_u64 (mp->last_seq_inbound),
14576          clib_net_to_host_u64 (mp->replay_window),
14577          clib_net_to_host_u64 (mp->total_data_size));
14578 }
14579
14580 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14581 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14582
14583 static void vl_api_ipsec_sa_details_t_handler_json
14584   (vl_api_ipsec_sa_details_t * mp)
14585 {
14586   vat_main_t *vam = &vat_main;
14587   vat_json_node_t *node = NULL;
14588   struct in_addr src_ip4, dst_ip4;
14589   struct in6_addr src_ip6, dst_ip6;
14590
14591   if (VAT_JSON_ARRAY != vam->json_tree.type)
14592     {
14593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14594       vat_json_init_array (&vam->json_tree);
14595     }
14596   node = vat_json_array_add (&vam->json_tree);
14597
14598   vat_json_init_object (node);
14599   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14600   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14601   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14602   vat_json_object_add_uint (node, "proto", mp->protocol);
14603   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14604   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14605   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14606   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14607   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14608   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14609   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14610                              mp->crypto_key_len);
14611   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14612                              mp->integ_key_len);
14613   if (mp->is_tunnel_ip6)
14614     {
14615       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14616       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14617       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14618       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14619     }
14620   else
14621     {
14622       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14623       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14624       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14625       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14626     }
14627   vat_json_object_add_uint (node, "replay_window",
14628                             clib_net_to_host_u64 (mp->replay_window));
14629   vat_json_object_add_uint (node, "total_data_size",
14630                             clib_net_to_host_u64 (mp->total_data_size));
14631
14632 }
14633
14634 static int
14635 api_ipsec_sa_dump (vat_main_t * vam)
14636 {
14637   unformat_input_t *i = vam->input;
14638   vl_api_ipsec_sa_dump_t *mp;
14639   vl_api_control_ping_t *mp_ping;
14640   u32 sa_id = ~0;
14641   int ret;
14642
14643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (i, "sa_id %d", &sa_id))
14646         ;
14647       else
14648         {
14649           clib_warning ("parse error '%U'", format_unformat_error, i);
14650           return -99;
14651         }
14652     }
14653
14654   M (IPSEC_SA_DUMP, mp);
14655
14656   mp->sa_id = ntohl (sa_id);
14657
14658   S (mp);
14659
14660   /* Use a control ping for synchronization */
14661   M (CONTROL_PING, mp_ping);
14662   S (mp_ping);
14663
14664   W (ret);
14665   return ret;
14666 }
14667
14668 static int
14669 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14670 {
14671   unformat_input_t *i = vam->input;
14672   vl_api_ipsec_tunnel_if_set_key_t *mp;
14673   u32 sw_if_index = ~0;
14674   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14675   u8 *key = 0;
14676   u32 alg = ~0;
14677   int ret;
14678
14679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14680     {
14681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14682         ;
14683       else
14684         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14685         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14686       else
14687         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14688         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14689       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14690         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14691       else
14692         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14693         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14694       else if (unformat (i, "%U", unformat_hex_string, &key))
14695         ;
14696       else
14697         {
14698           clib_warning ("parse error '%U'", format_unformat_error, i);
14699           return -99;
14700         }
14701     }
14702
14703   if (sw_if_index == ~0)
14704     {
14705       errmsg ("interface must be specified");
14706       return -99;
14707     }
14708
14709   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14710     {
14711       errmsg ("key type must be specified");
14712       return -99;
14713     }
14714
14715   if (alg == ~0)
14716     {
14717       errmsg ("algorithm must be specified");
14718       return -99;
14719     }
14720
14721   if (vec_len (key) == 0)
14722     {
14723       errmsg ("key must be specified");
14724       return -99;
14725     }
14726
14727   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14728
14729   mp->sw_if_index = htonl (sw_if_index);
14730   mp->alg = alg;
14731   mp->key_type = key_type;
14732   mp->key_len = vec_len (key);
14733   clib_memcpy (mp->key, key, vec_len (key));
14734
14735   S (mp);
14736   W (ret);
14737
14738   return ret;
14739 }
14740
14741 static int
14742 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14743 {
14744   unformat_input_t *i = vam->input;
14745   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14746   u32 sw_if_index = ~0;
14747   u32 sa_id = ~0;
14748   u8 is_outbound = (u8) ~ 0;
14749   int ret;
14750
14751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14752     {
14753       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14754         ;
14755       else if (unformat (i, "sa_id %d", &sa_id))
14756         ;
14757       else if (unformat (i, "outbound"))
14758         is_outbound = 1;
14759       else if (unformat (i, "inbound"))
14760         is_outbound = 0;
14761       else
14762         {
14763           clib_warning ("parse error '%U'", format_unformat_error, i);
14764           return -99;
14765         }
14766     }
14767
14768   if (sw_if_index == ~0)
14769     {
14770       errmsg ("interface must be specified");
14771       return -99;
14772     }
14773
14774   if (sa_id == ~0)
14775     {
14776       errmsg ("SA ID must be specified");
14777       return -99;
14778     }
14779
14780   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14781
14782   mp->sw_if_index = htonl (sw_if_index);
14783   mp->sa_id = htonl (sa_id);
14784   mp->is_outbound = is_outbound;
14785
14786   S (mp);
14787   W (ret);
14788
14789   return ret;
14790 }
14791
14792 static int
14793 api_ikev2_profile_add_del (vat_main_t * vam)
14794 {
14795   unformat_input_t *i = vam->input;
14796   vl_api_ikev2_profile_add_del_t *mp;
14797   u8 is_add = 1;
14798   u8 *name = 0;
14799   int ret;
14800
14801   const char *valid_chars = "a-zA-Z0-9_";
14802
14803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (unformat (i, "del"))
14806         is_add = 0;
14807       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14808         vec_add1 (name, 0);
14809       else
14810         {
14811           errmsg ("parse error '%U'", format_unformat_error, i);
14812           return -99;
14813         }
14814     }
14815
14816   if (!vec_len (name))
14817     {
14818       errmsg ("profile name must be specified");
14819       return -99;
14820     }
14821
14822   if (vec_len (name) > 64)
14823     {
14824       errmsg ("profile name too long");
14825       return -99;
14826     }
14827
14828   M (IKEV2_PROFILE_ADD_DEL, mp);
14829
14830   clib_memcpy (mp->name, name, vec_len (name));
14831   mp->is_add = is_add;
14832   vec_free (name);
14833
14834   S (mp);
14835   W (ret);
14836   return ret;
14837 }
14838
14839 static int
14840 api_ikev2_profile_set_auth (vat_main_t * vam)
14841 {
14842   unformat_input_t *i = vam->input;
14843   vl_api_ikev2_profile_set_auth_t *mp;
14844   u8 *name = 0;
14845   u8 *data = 0;
14846   u32 auth_method = 0;
14847   u8 is_hex = 0;
14848   int ret;
14849
14850   const char *valid_chars = "a-zA-Z0-9_";
14851
14852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14853     {
14854       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14855         vec_add1 (name, 0);
14856       else if (unformat (i, "auth_method %U",
14857                          unformat_ikev2_auth_method, &auth_method))
14858         ;
14859       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14860         is_hex = 1;
14861       else if (unformat (i, "auth_data %v", &data))
14862         ;
14863       else
14864         {
14865           errmsg ("parse error '%U'", format_unformat_error, i);
14866           return -99;
14867         }
14868     }
14869
14870   if (!vec_len (name))
14871     {
14872       errmsg ("profile name must be specified");
14873       return -99;
14874     }
14875
14876   if (vec_len (name) > 64)
14877     {
14878       errmsg ("profile name too long");
14879       return -99;
14880     }
14881
14882   if (!vec_len (data))
14883     {
14884       errmsg ("auth_data must be specified");
14885       return -99;
14886     }
14887
14888   if (!auth_method)
14889     {
14890       errmsg ("auth_method must be specified");
14891       return -99;
14892     }
14893
14894   M (IKEV2_PROFILE_SET_AUTH, mp);
14895
14896   mp->is_hex = is_hex;
14897   mp->auth_method = (u8) auth_method;
14898   mp->data_len = vec_len (data);
14899   clib_memcpy (mp->name, name, vec_len (name));
14900   clib_memcpy (mp->data, data, vec_len (data));
14901   vec_free (name);
14902   vec_free (data);
14903
14904   S (mp);
14905   W (ret);
14906   return ret;
14907 }
14908
14909 static int
14910 api_ikev2_profile_set_id (vat_main_t * vam)
14911 {
14912   unformat_input_t *i = vam->input;
14913   vl_api_ikev2_profile_set_id_t *mp;
14914   u8 *name = 0;
14915   u8 *data = 0;
14916   u8 is_local = 0;
14917   u32 id_type = 0;
14918   ip4_address_t ip4;
14919   int ret;
14920
14921   const char *valid_chars = "a-zA-Z0-9_";
14922
14923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14926         vec_add1 (name, 0);
14927       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14928         ;
14929       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14930         {
14931           data = vec_new (u8, 4);
14932           clib_memcpy (data, ip4.as_u8, 4);
14933         }
14934       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14935         ;
14936       else if (unformat (i, "id_data %v", &data))
14937         ;
14938       else if (unformat (i, "local"))
14939         is_local = 1;
14940       else if (unformat (i, "remote"))
14941         is_local = 0;
14942       else
14943         {
14944           errmsg ("parse error '%U'", format_unformat_error, i);
14945           return -99;
14946         }
14947     }
14948
14949   if (!vec_len (name))
14950     {
14951       errmsg ("profile name must be specified");
14952       return -99;
14953     }
14954
14955   if (vec_len (name) > 64)
14956     {
14957       errmsg ("profile name too long");
14958       return -99;
14959     }
14960
14961   if (!vec_len (data))
14962     {
14963       errmsg ("id_data must be specified");
14964       return -99;
14965     }
14966
14967   if (!id_type)
14968     {
14969       errmsg ("id_type must be specified");
14970       return -99;
14971     }
14972
14973   M (IKEV2_PROFILE_SET_ID, mp);
14974
14975   mp->is_local = is_local;
14976   mp->id_type = (u8) id_type;
14977   mp->data_len = vec_len (data);
14978   clib_memcpy (mp->name, name, vec_len (name));
14979   clib_memcpy (mp->data, data, vec_len (data));
14980   vec_free (name);
14981   vec_free (data);
14982
14983   S (mp);
14984   W (ret);
14985   return ret;
14986 }
14987
14988 static int
14989 api_ikev2_profile_set_ts (vat_main_t * vam)
14990 {
14991   unformat_input_t *i = vam->input;
14992   vl_api_ikev2_profile_set_ts_t *mp;
14993   u8 *name = 0;
14994   u8 is_local = 0;
14995   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14996   ip4_address_t start_addr, end_addr;
14997
14998   const char *valid_chars = "a-zA-Z0-9_";
14999   int ret;
15000
15001   start_addr.as_u32 = 0;
15002   end_addr.as_u32 = (u32) ~ 0;
15003
15004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15005     {
15006       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15007         vec_add1 (name, 0);
15008       else if (unformat (i, "protocol %d", &proto))
15009         ;
15010       else if (unformat (i, "start_port %d", &start_port))
15011         ;
15012       else if (unformat (i, "end_port %d", &end_port))
15013         ;
15014       else
15015         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15016         ;
15017       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15018         ;
15019       else if (unformat (i, "local"))
15020         is_local = 1;
15021       else if (unformat (i, "remote"))
15022         is_local = 0;
15023       else
15024         {
15025           errmsg ("parse error '%U'", format_unformat_error, i);
15026           return -99;
15027         }
15028     }
15029
15030   if (!vec_len (name))
15031     {
15032       errmsg ("profile name must be specified");
15033       return -99;
15034     }
15035
15036   if (vec_len (name) > 64)
15037     {
15038       errmsg ("profile name too long");
15039       return -99;
15040     }
15041
15042   M (IKEV2_PROFILE_SET_TS, mp);
15043
15044   mp->is_local = is_local;
15045   mp->proto = (u8) proto;
15046   mp->start_port = (u16) start_port;
15047   mp->end_port = (u16) end_port;
15048   mp->start_addr = start_addr.as_u32;
15049   mp->end_addr = end_addr.as_u32;
15050   clib_memcpy (mp->name, name, vec_len (name));
15051   vec_free (name);
15052
15053   S (mp);
15054   W (ret);
15055   return ret;
15056 }
15057
15058 static int
15059 api_ikev2_set_local_key (vat_main_t * vam)
15060 {
15061   unformat_input_t *i = vam->input;
15062   vl_api_ikev2_set_local_key_t *mp;
15063   u8 *file = 0;
15064   int ret;
15065
15066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15067     {
15068       if (unformat (i, "file %v", &file))
15069         vec_add1 (file, 0);
15070       else
15071         {
15072           errmsg ("parse error '%U'", format_unformat_error, i);
15073           return -99;
15074         }
15075     }
15076
15077   if (!vec_len (file))
15078     {
15079       errmsg ("RSA key file must be specified");
15080       return -99;
15081     }
15082
15083   if (vec_len (file) > 256)
15084     {
15085       errmsg ("file name too long");
15086       return -99;
15087     }
15088
15089   M (IKEV2_SET_LOCAL_KEY, mp);
15090
15091   clib_memcpy (mp->key_file, file, vec_len (file));
15092   vec_free (file);
15093
15094   S (mp);
15095   W (ret);
15096   return ret;
15097 }
15098
15099 static int
15100 api_ikev2_set_responder (vat_main_t * vam)
15101 {
15102   unformat_input_t *i = vam->input;
15103   vl_api_ikev2_set_responder_t *mp;
15104   int ret;
15105   u8 *name = 0;
15106   u32 sw_if_index = ~0;
15107   ip4_address_t address;
15108
15109   const char *valid_chars = "a-zA-Z0-9_";
15110
15111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15112     {
15113       if (unformat
15114           (i, "%U interface %d address %U", unformat_token, valid_chars,
15115            &name, &sw_if_index, unformat_ip4_address, &address))
15116         vec_add1 (name, 0);
15117       else
15118         {
15119           errmsg ("parse error '%U'", format_unformat_error, i);
15120           return -99;
15121         }
15122     }
15123
15124   if (!vec_len (name))
15125     {
15126       errmsg ("profile name must be specified");
15127       return -99;
15128     }
15129
15130   if (vec_len (name) > 64)
15131     {
15132       errmsg ("profile name too long");
15133       return -99;
15134     }
15135
15136   M (IKEV2_SET_RESPONDER, mp);
15137
15138   clib_memcpy (mp->name, name, vec_len (name));
15139   vec_free (name);
15140
15141   mp->sw_if_index = sw_if_index;
15142   clib_memcpy (mp->address, &address, sizeof (address));
15143
15144   S (mp);
15145   W (ret);
15146   return ret;
15147 }
15148
15149 static int
15150 api_ikev2_set_ike_transforms (vat_main_t * vam)
15151 {
15152   unformat_input_t *i = vam->input;
15153   vl_api_ikev2_set_ike_transforms_t *mp;
15154   int ret;
15155   u8 *name = 0;
15156   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15157
15158   const char *valid_chars = "a-zA-Z0-9_";
15159
15160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15161     {
15162       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15163                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15164         vec_add1 (name, 0);
15165       else
15166         {
15167           errmsg ("parse error '%U'", format_unformat_error, i);
15168           return -99;
15169         }
15170     }
15171
15172   if (!vec_len (name))
15173     {
15174       errmsg ("profile name must be specified");
15175       return -99;
15176     }
15177
15178   if (vec_len (name) > 64)
15179     {
15180       errmsg ("profile name too long");
15181       return -99;
15182     }
15183
15184   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15185
15186   clib_memcpy (mp->name, name, vec_len (name));
15187   vec_free (name);
15188   mp->crypto_alg = crypto_alg;
15189   mp->crypto_key_size = crypto_key_size;
15190   mp->integ_alg = integ_alg;
15191   mp->dh_group = dh_group;
15192
15193   S (mp);
15194   W (ret);
15195   return ret;
15196 }
15197
15198
15199 static int
15200 api_ikev2_set_esp_transforms (vat_main_t * vam)
15201 {
15202   unformat_input_t *i = vam->input;
15203   vl_api_ikev2_set_esp_transforms_t *mp;
15204   int ret;
15205   u8 *name = 0;
15206   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15207
15208   const char *valid_chars = "a-zA-Z0-9_";
15209
15210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15211     {
15212       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15213                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15214         vec_add1 (name, 0);
15215       else
15216         {
15217           errmsg ("parse error '%U'", format_unformat_error, i);
15218           return -99;
15219         }
15220     }
15221
15222   if (!vec_len (name))
15223     {
15224       errmsg ("profile name must be specified");
15225       return -99;
15226     }
15227
15228   if (vec_len (name) > 64)
15229     {
15230       errmsg ("profile name too long");
15231       return -99;
15232     }
15233
15234   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15235
15236   clib_memcpy (mp->name, name, vec_len (name));
15237   vec_free (name);
15238   mp->crypto_alg = crypto_alg;
15239   mp->crypto_key_size = crypto_key_size;
15240   mp->integ_alg = integ_alg;
15241   mp->dh_group = dh_group;
15242
15243   S (mp);
15244   W (ret);
15245   return ret;
15246 }
15247
15248 static int
15249 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15250 {
15251   unformat_input_t *i = vam->input;
15252   vl_api_ikev2_set_sa_lifetime_t *mp;
15253   int ret;
15254   u8 *name = 0;
15255   u64 lifetime, lifetime_maxdata;
15256   u32 lifetime_jitter, handover;
15257
15258   const char *valid_chars = "a-zA-Z0-9_";
15259
15260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15261     {
15262       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15263                     &lifetime, &lifetime_jitter, &handover,
15264                     &lifetime_maxdata))
15265         vec_add1 (name, 0);
15266       else
15267         {
15268           errmsg ("parse error '%U'", format_unformat_error, i);
15269           return -99;
15270         }
15271     }
15272
15273   if (!vec_len (name))
15274     {
15275       errmsg ("profile name must be specified");
15276       return -99;
15277     }
15278
15279   if (vec_len (name) > 64)
15280     {
15281       errmsg ("profile name too long");
15282       return -99;
15283     }
15284
15285   M (IKEV2_SET_SA_LIFETIME, mp);
15286
15287   clib_memcpy (mp->name, name, vec_len (name));
15288   vec_free (name);
15289   mp->lifetime = lifetime;
15290   mp->lifetime_jitter = lifetime_jitter;
15291   mp->handover = handover;
15292   mp->lifetime_maxdata = lifetime_maxdata;
15293
15294   S (mp);
15295   W (ret);
15296   return ret;
15297 }
15298
15299 static int
15300 api_ikev2_initiate_sa_init (vat_main_t * vam)
15301 {
15302   unformat_input_t *i = vam->input;
15303   vl_api_ikev2_initiate_sa_init_t *mp;
15304   int ret;
15305   u8 *name = 0;
15306
15307   const char *valid_chars = "a-zA-Z0-9_";
15308
15309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15310     {
15311       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15312         vec_add1 (name, 0);
15313       else
15314         {
15315           errmsg ("parse error '%U'", format_unformat_error, i);
15316           return -99;
15317         }
15318     }
15319
15320   if (!vec_len (name))
15321     {
15322       errmsg ("profile name must be specified");
15323       return -99;
15324     }
15325
15326   if (vec_len (name) > 64)
15327     {
15328       errmsg ("profile name too long");
15329       return -99;
15330     }
15331
15332   M (IKEV2_INITIATE_SA_INIT, mp);
15333
15334   clib_memcpy (mp->name, name, vec_len (name));
15335   vec_free (name);
15336
15337   S (mp);
15338   W (ret);
15339   return ret;
15340 }
15341
15342 static int
15343 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15344 {
15345   unformat_input_t *i = vam->input;
15346   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15347   int ret;
15348   u64 ispi;
15349
15350
15351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15352     {
15353       if (unformat (i, "%lx", &ispi))
15354         ;
15355       else
15356         {
15357           errmsg ("parse error '%U'", format_unformat_error, i);
15358           return -99;
15359         }
15360     }
15361
15362   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15363
15364   mp->ispi = ispi;
15365
15366   S (mp);
15367   W (ret);
15368   return ret;
15369 }
15370
15371 static int
15372 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15373 {
15374   unformat_input_t *i = vam->input;
15375   vl_api_ikev2_initiate_del_child_sa_t *mp;
15376   int ret;
15377   u32 ispi;
15378
15379
15380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15381     {
15382       if (unformat (i, "%x", &ispi))
15383         ;
15384       else
15385         {
15386           errmsg ("parse error '%U'", format_unformat_error, i);
15387           return -99;
15388         }
15389     }
15390
15391   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15392
15393   mp->ispi = ispi;
15394
15395   S (mp);
15396   W (ret);
15397   return ret;
15398 }
15399
15400 static int
15401 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15402 {
15403   unformat_input_t *i = vam->input;
15404   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15405   int ret;
15406   u32 ispi;
15407
15408
15409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15410     {
15411       if (unformat (i, "%x", &ispi))
15412         ;
15413       else
15414         {
15415           errmsg ("parse error '%U'", format_unformat_error, i);
15416           return -99;
15417         }
15418     }
15419
15420   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15421
15422   mp->ispi = ispi;
15423
15424   S (mp);
15425   W (ret);
15426   return ret;
15427 }
15428
15429 /*
15430  * MAP
15431  */
15432 static int
15433 api_map_add_domain (vat_main_t * vam)
15434 {
15435   unformat_input_t *i = vam->input;
15436   vl_api_map_add_domain_t *mp;
15437
15438   ip4_address_t ip4_prefix;
15439   ip6_address_t ip6_prefix;
15440   ip6_address_t ip6_src;
15441   u32 num_m_args = 0;
15442   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15443     0, psid_length = 0;
15444   u8 is_translation = 0;
15445   u32 mtu = 0;
15446   u32 ip6_src_len = 128;
15447   int ret;
15448
15449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15450     {
15451       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15452                     &ip4_prefix, &ip4_prefix_len))
15453         num_m_args++;
15454       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15455                          &ip6_prefix, &ip6_prefix_len))
15456         num_m_args++;
15457       else
15458         if (unformat
15459             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15460              &ip6_src_len))
15461         num_m_args++;
15462       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15463         num_m_args++;
15464       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15465         num_m_args++;
15466       else if (unformat (i, "psid-offset %d", &psid_offset))
15467         num_m_args++;
15468       else if (unformat (i, "psid-len %d", &psid_length))
15469         num_m_args++;
15470       else if (unformat (i, "mtu %d", &mtu))
15471         num_m_args++;
15472       else if (unformat (i, "map-t"))
15473         is_translation = 1;
15474       else
15475         {
15476           clib_warning ("parse error '%U'", format_unformat_error, i);
15477           return -99;
15478         }
15479     }
15480
15481   if (num_m_args < 3)
15482     {
15483       errmsg ("mandatory argument(s) missing");
15484       return -99;
15485     }
15486
15487   /* Construct the API message */
15488   M (MAP_ADD_DOMAIN, mp);
15489
15490   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15491   mp->ip4_prefix_len = ip4_prefix_len;
15492
15493   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15494   mp->ip6_prefix_len = ip6_prefix_len;
15495
15496   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15497   mp->ip6_src_prefix_len = ip6_src_len;
15498
15499   mp->ea_bits_len = ea_bits_len;
15500   mp->psid_offset = psid_offset;
15501   mp->psid_length = psid_length;
15502   mp->is_translation = is_translation;
15503   mp->mtu = htons (mtu);
15504
15505   /* send it... */
15506   S (mp);
15507
15508   /* Wait for a reply, return good/bad news  */
15509   W (ret);
15510   return ret;
15511 }
15512
15513 static int
15514 api_map_del_domain (vat_main_t * vam)
15515 {
15516   unformat_input_t *i = vam->input;
15517   vl_api_map_del_domain_t *mp;
15518
15519   u32 num_m_args = 0;
15520   u32 index;
15521   int ret;
15522
15523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15524     {
15525       if (unformat (i, "index %d", &index))
15526         num_m_args++;
15527       else
15528         {
15529           clib_warning ("parse error '%U'", format_unformat_error, i);
15530           return -99;
15531         }
15532     }
15533
15534   if (num_m_args != 1)
15535     {
15536       errmsg ("mandatory argument(s) missing");
15537       return -99;
15538     }
15539
15540   /* Construct the API message */
15541   M (MAP_DEL_DOMAIN, mp);
15542
15543   mp->index = ntohl (index);
15544
15545   /* send it... */
15546   S (mp);
15547
15548   /* Wait for a reply, return good/bad news  */
15549   W (ret);
15550   return ret;
15551 }
15552
15553 static int
15554 api_map_add_del_rule (vat_main_t * vam)
15555 {
15556   unformat_input_t *i = vam->input;
15557   vl_api_map_add_del_rule_t *mp;
15558   u8 is_add = 1;
15559   ip6_address_t ip6_dst;
15560   u32 num_m_args = 0, index, psid = 0;
15561   int ret;
15562
15563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15564     {
15565       if (unformat (i, "index %d", &index))
15566         num_m_args++;
15567       else if (unformat (i, "psid %d", &psid))
15568         num_m_args++;
15569       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15570         num_m_args++;
15571       else if (unformat (i, "del"))
15572         {
15573           is_add = 0;
15574         }
15575       else
15576         {
15577           clib_warning ("parse error '%U'", format_unformat_error, i);
15578           return -99;
15579         }
15580     }
15581
15582   /* Construct the API message */
15583   M (MAP_ADD_DEL_RULE, mp);
15584
15585   mp->index = ntohl (index);
15586   mp->is_add = is_add;
15587   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15588   mp->psid = ntohs (psid);
15589
15590   /* send it... */
15591   S (mp);
15592
15593   /* Wait for a reply, return good/bad news  */
15594   W (ret);
15595   return ret;
15596 }
15597
15598 static int
15599 api_map_domain_dump (vat_main_t * vam)
15600 {
15601   vl_api_map_domain_dump_t *mp;
15602   vl_api_control_ping_t *mp_ping;
15603   int ret;
15604
15605   /* Construct the API message */
15606   M (MAP_DOMAIN_DUMP, mp);
15607
15608   /* send it... */
15609   S (mp);
15610
15611   /* Use a control ping for synchronization */
15612   MPING (CONTROL_PING, mp_ping);
15613   S (mp_ping);
15614
15615   W (ret);
15616   return ret;
15617 }
15618
15619 static int
15620 api_map_rule_dump (vat_main_t * vam)
15621 {
15622   unformat_input_t *i = vam->input;
15623   vl_api_map_rule_dump_t *mp;
15624   vl_api_control_ping_t *mp_ping;
15625   u32 domain_index = ~0;
15626   int ret;
15627
15628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15629     {
15630       if (unformat (i, "index %u", &domain_index))
15631         ;
15632       else
15633         break;
15634     }
15635
15636   if (domain_index == ~0)
15637     {
15638       clib_warning ("parse error: domain index expected");
15639       return -99;
15640     }
15641
15642   /* Construct the API message */
15643   M (MAP_RULE_DUMP, mp);
15644
15645   mp->domain_index = htonl (domain_index);
15646
15647   /* send it... */
15648   S (mp);
15649
15650   /* Use a control ping for synchronization */
15651   MPING (CONTROL_PING, mp_ping);
15652   S (mp_ping);
15653
15654   W (ret);
15655   return ret;
15656 }
15657
15658 static void vl_api_map_add_domain_reply_t_handler
15659   (vl_api_map_add_domain_reply_t * mp)
15660 {
15661   vat_main_t *vam = &vat_main;
15662   i32 retval = ntohl (mp->retval);
15663
15664   if (vam->async_mode)
15665     {
15666       vam->async_errors += (retval < 0);
15667     }
15668   else
15669     {
15670       vam->retval = retval;
15671       vam->result_ready = 1;
15672     }
15673 }
15674
15675 static void vl_api_map_add_domain_reply_t_handler_json
15676   (vl_api_map_add_domain_reply_t * mp)
15677 {
15678   vat_main_t *vam = &vat_main;
15679   vat_json_node_t node;
15680
15681   vat_json_init_object (&node);
15682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15683   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15684
15685   vat_json_print (vam->ofp, &node);
15686   vat_json_free (&node);
15687
15688   vam->retval = ntohl (mp->retval);
15689   vam->result_ready = 1;
15690 }
15691
15692 static int
15693 api_get_first_msg_id (vat_main_t * vam)
15694 {
15695   vl_api_get_first_msg_id_t *mp;
15696   unformat_input_t *i = vam->input;
15697   u8 *name;
15698   u8 name_set = 0;
15699   int ret;
15700
15701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (i, "client %s", &name))
15704         name_set = 1;
15705       else
15706         break;
15707     }
15708
15709   if (name_set == 0)
15710     {
15711       errmsg ("missing client name");
15712       return -99;
15713     }
15714   vec_add1 (name, 0);
15715
15716   if (vec_len (name) > 63)
15717     {
15718       errmsg ("client name too long");
15719       return -99;
15720     }
15721
15722   M (GET_FIRST_MSG_ID, mp);
15723   clib_memcpy (mp->name, name, vec_len (name));
15724   S (mp);
15725   W (ret);
15726   return ret;
15727 }
15728
15729 static int
15730 api_cop_interface_enable_disable (vat_main_t * vam)
15731 {
15732   unformat_input_t *line_input = vam->input;
15733   vl_api_cop_interface_enable_disable_t *mp;
15734   u32 sw_if_index = ~0;
15735   u8 enable_disable = 1;
15736   int ret;
15737
15738   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15739     {
15740       if (unformat (line_input, "disable"))
15741         enable_disable = 0;
15742       if (unformat (line_input, "enable"))
15743         enable_disable = 1;
15744       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15745                          vam, &sw_if_index))
15746         ;
15747       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15748         ;
15749       else
15750         break;
15751     }
15752
15753   if (sw_if_index == ~0)
15754     {
15755       errmsg ("missing interface name or sw_if_index");
15756       return -99;
15757     }
15758
15759   /* Construct the API message */
15760   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15761   mp->sw_if_index = ntohl (sw_if_index);
15762   mp->enable_disable = enable_disable;
15763
15764   /* send it... */
15765   S (mp);
15766   /* Wait for the reply */
15767   W (ret);
15768   return ret;
15769 }
15770
15771 static int
15772 api_cop_whitelist_enable_disable (vat_main_t * vam)
15773 {
15774   unformat_input_t *line_input = vam->input;
15775   vl_api_cop_whitelist_enable_disable_t *mp;
15776   u32 sw_if_index = ~0;
15777   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15778   u32 fib_id = 0;
15779   int ret;
15780
15781   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15782     {
15783       if (unformat (line_input, "ip4"))
15784         ip4 = 1;
15785       else if (unformat (line_input, "ip6"))
15786         ip6 = 1;
15787       else if (unformat (line_input, "default"))
15788         default_cop = 1;
15789       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15790                          vam, &sw_if_index))
15791         ;
15792       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15793         ;
15794       else if (unformat (line_input, "fib-id %d", &fib_id))
15795         ;
15796       else
15797         break;
15798     }
15799
15800   if (sw_if_index == ~0)
15801     {
15802       errmsg ("missing interface name or sw_if_index");
15803       return -99;
15804     }
15805
15806   /* Construct the API message */
15807   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15808   mp->sw_if_index = ntohl (sw_if_index);
15809   mp->fib_id = ntohl (fib_id);
15810   mp->ip4 = ip4;
15811   mp->ip6 = ip6;
15812   mp->default_cop = default_cop;
15813
15814   /* send it... */
15815   S (mp);
15816   /* Wait for the reply */
15817   W (ret);
15818   return ret;
15819 }
15820
15821 static int
15822 api_get_node_graph (vat_main_t * vam)
15823 {
15824   vl_api_get_node_graph_t *mp;
15825   int ret;
15826
15827   M (GET_NODE_GRAPH, mp);
15828
15829   /* send it... */
15830   S (mp);
15831   /* Wait for the reply */
15832   W (ret);
15833   return ret;
15834 }
15835
15836 /* *INDENT-OFF* */
15837 /** Used for parsing LISP eids */
15838 typedef CLIB_PACKED(struct{
15839   u8 addr[16];   /**< eid address */
15840   u32 len;       /**< prefix length if IP */
15841   u8 type;      /**< type of eid */
15842 }) lisp_eid_vat_t;
15843 /* *INDENT-ON* */
15844
15845 static uword
15846 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15847 {
15848   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15849
15850   memset (a, 0, sizeof (a[0]));
15851
15852   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15853     {
15854       a->type = 0;              /* ipv4 type */
15855     }
15856   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15857     {
15858       a->type = 1;              /* ipv6 type */
15859     }
15860   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15861     {
15862       a->type = 2;              /* mac type */
15863     }
15864   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15865     {
15866       a->type = 3;              /* NSH type */
15867       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15868       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15869     }
15870   else
15871     {
15872       return 0;
15873     }
15874
15875   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15876     {
15877       return 0;
15878     }
15879
15880   return 1;
15881 }
15882
15883 static int
15884 lisp_eid_size_vat (u8 type)
15885 {
15886   switch (type)
15887     {
15888     case 0:
15889       return 4;
15890     case 1:
15891       return 16;
15892     case 2:
15893       return 6;
15894     case 3:
15895       return 5;
15896     }
15897   return 0;
15898 }
15899
15900 static void
15901 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15902 {
15903   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15904 }
15905
15906 static int
15907 api_one_add_del_locator_set (vat_main_t * vam)
15908 {
15909   unformat_input_t *input = vam->input;
15910   vl_api_one_add_del_locator_set_t *mp;
15911   u8 is_add = 1;
15912   u8 *locator_set_name = NULL;
15913   u8 locator_set_name_set = 0;
15914   vl_api_local_locator_t locator, *locators = 0;
15915   u32 sw_if_index, priority, weight;
15916   u32 data_len = 0;
15917
15918   int ret;
15919   /* Parse args required to build the message */
15920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15921     {
15922       if (unformat (input, "del"))
15923         {
15924           is_add = 0;
15925         }
15926       else if (unformat (input, "locator-set %s", &locator_set_name))
15927         {
15928           locator_set_name_set = 1;
15929         }
15930       else if (unformat (input, "sw_if_index %u p %u w %u",
15931                          &sw_if_index, &priority, &weight))
15932         {
15933           locator.sw_if_index = htonl (sw_if_index);
15934           locator.priority = priority;
15935           locator.weight = weight;
15936           vec_add1 (locators, locator);
15937         }
15938       else
15939         if (unformat
15940             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15941              &sw_if_index, &priority, &weight))
15942         {
15943           locator.sw_if_index = htonl (sw_if_index);
15944           locator.priority = priority;
15945           locator.weight = weight;
15946           vec_add1 (locators, locator);
15947         }
15948       else
15949         break;
15950     }
15951
15952   if (locator_set_name_set == 0)
15953     {
15954       errmsg ("missing locator-set name");
15955       vec_free (locators);
15956       return -99;
15957     }
15958
15959   if (vec_len (locator_set_name) > 64)
15960     {
15961       errmsg ("locator-set name too long");
15962       vec_free (locator_set_name);
15963       vec_free (locators);
15964       return -99;
15965     }
15966   vec_add1 (locator_set_name, 0);
15967
15968   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15969
15970   /* Construct the API message */
15971   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15972
15973   mp->is_add = is_add;
15974   clib_memcpy (mp->locator_set_name, locator_set_name,
15975                vec_len (locator_set_name));
15976   vec_free (locator_set_name);
15977
15978   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15979   if (locators)
15980     clib_memcpy (mp->locators, locators, data_len);
15981   vec_free (locators);
15982
15983   /* send it... */
15984   S (mp);
15985
15986   /* Wait for a reply... */
15987   W (ret);
15988   return ret;
15989 }
15990
15991 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15992
15993 static int
15994 api_one_add_del_locator (vat_main_t * vam)
15995 {
15996   unformat_input_t *input = vam->input;
15997   vl_api_one_add_del_locator_t *mp;
15998   u32 tmp_if_index = ~0;
15999   u32 sw_if_index = ~0;
16000   u8 sw_if_index_set = 0;
16001   u8 sw_if_index_if_name_set = 0;
16002   u32 priority = ~0;
16003   u8 priority_set = 0;
16004   u32 weight = ~0;
16005   u8 weight_set = 0;
16006   u8 is_add = 1;
16007   u8 *locator_set_name = NULL;
16008   u8 locator_set_name_set = 0;
16009   int ret;
16010
16011   /* Parse args required to build the message */
16012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16013     {
16014       if (unformat (input, "del"))
16015         {
16016           is_add = 0;
16017         }
16018       else if (unformat (input, "locator-set %s", &locator_set_name))
16019         {
16020           locator_set_name_set = 1;
16021         }
16022       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16023                          &tmp_if_index))
16024         {
16025           sw_if_index_if_name_set = 1;
16026           sw_if_index = tmp_if_index;
16027         }
16028       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16029         {
16030           sw_if_index_set = 1;
16031           sw_if_index = tmp_if_index;
16032         }
16033       else if (unformat (input, "p %d", &priority))
16034         {
16035           priority_set = 1;
16036         }
16037       else if (unformat (input, "w %d", &weight))
16038         {
16039           weight_set = 1;
16040         }
16041       else
16042         break;
16043     }
16044
16045   if (locator_set_name_set == 0)
16046     {
16047       errmsg ("missing locator-set name");
16048       return -99;
16049     }
16050
16051   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16052     {
16053       errmsg ("missing sw_if_index");
16054       vec_free (locator_set_name);
16055       return -99;
16056     }
16057
16058   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16059     {
16060       errmsg ("cannot use both params interface name and sw_if_index");
16061       vec_free (locator_set_name);
16062       return -99;
16063     }
16064
16065   if (priority_set == 0)
16066     {
16067       errmsg ("missing locator-set priority");
16068       vec_free (locator_set_name);
16069       return -99;
16070     }
16071
16072   if (weight_set == 0)
16073     {
16074       errmsg ("missing locator-set weight");
16075       vec_free (locator_set_name);
16076       return -99;
16077     }
16078
16079   if (vec_len (locator_set_name) > 64)
16080     {
16081       errmsg ("locator-set name too long");
16082       vec_free (locator_set_name);
16083       return -99;
16084     }
16085   vec_add1 (locator_set_name, 0);
16086
16087   /* Construct the API message */
16088   M (ONE_ADD_DEL_LOCATOR, mp);
16089
16090   mp->is_add = is_add;
16091   mp->sw_if_index = ntohl (sw_if_index);
16092   mp->priority = priority;
16093   mp->weight = weight;
16094   clib_memcpy (mp->locator_set_name, locator_set_name,
16095                vec_len (locator_set_name));
16096   vec_free (locator_set_name);
16097
16098   /* send it... */
16099   S (mp);
16100
16101   /* Wait for a reply... */
16102   W (ret);
16103   return ret;
16104 }
16105
16106 #define api_lisp_add_del_locator api_one_add_del_locator
16107
16108 uword
16109 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16110 {
16111   u32 *key_id = va_arg (*args, u32 *);
16112   u8 *s = 0;
16113
16114   if (unformat (input, "%s", &s))
16115     {
16116       if (!strcmp ((char *) s, "sha1"))
16117         key_id[0] = HMAC_SHA_1_96;
16118       else if (!strcmp ((char *) s, "sha256"))
16119         key_id[0] = HMAC_SHA_256_128;
16120       else
16121         {
16122           clib_warning ("invalid key_id: '%s'", s);
16123           key_id[0] = HMAC_NO_KEY;
16124         }
16125     }
16126   else
16127     return 0;
16128
16129   vec_free (s);
16130   return 1;
16131 }
16132
16133 static int
16134 api_one_add_del_local_eid (vat_main_t * vam)
16135 {
16136   unformat_input_t *input = vam->input;
16137   vl_api_one_add_del_local_eid_t *mp;
16138   u8 is_add = 1;
16139   u8 eid_set = 0;
16140   lisp_eid_vat_t _eid, *eid = &_eid;
16141   u8 *locator_set_name = 0;
16142   u8 locator_set_name_set = 0;
16143   u32 vni = 0;
16144   u16 key_id = 0;
16145   u8 *key = 0;
16146   int ret;
16147
16148   /* Parse args required to build the message */
16149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16150     {
16151       if (unformat (input, "del"))
16152         {
16153           is_add = 0;
16154         }
16155       else if (unformat (input, "vni %d", &vni))
16156         {
16157           ;
16158         }
16159       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16160         {
16161           eid_set = 1;
16162         }
16163       else if (unformat (input, "locator-set %s", &locator_set_name))
16164         {
16165           locator_set_name_set = 1;
16166         }
16167       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16168         ;
16169       else if (unformat (input, "secret-key %_%v%_", &key))
16170         ;
16171       else
16172         break;
16173     }
16174
16175   if (locator_set_name_set == 0)
16176     {
16177       errmsg ("missing locator-set name");
16178       return -99;
16179     }
16180
16181   if (0 == eid_set)
16182     {
16183       errmsg ("EID address not set!");
16184       vec_free (locator_set_name);
16185       return -99;
16186     }
16187
16188   if (key && (0 == key_id))
16189     {
16190       errmsg ("invalid key_id!");
16191       return -99;
16192     }
16193
16194   if (vec_len (key) > 64)
16195     {
16196       errmsg ("key too long");
16197       vec_free (key);
16198       return -99;
16199     }
16200
16201   if (vec_len (locator_set_name) > 64)
16202     {
16203       errmsg ("locator-set name too long");
16204       vec_free (locator_set_name);
16205       return -99;
16206     }
16207   vec_add1 (locator_set_name, 0);
16208
16209   /* Construct the API message */
16210   M (ONE_ADD_DEL_LOCAL_EID, mp);
16211
16212   mp->is_add = is_add;
16213   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16214   mp->eid_type = eid->type;
16215   mp->prefix_len = eid->len;
16216   mp->vni = clib_host_to_net_u32 (vni);
16217   mp->key_id = clib_host_to_net_u16 (key_id);
16218   clib_memcpy (mp->locator_set_name, locator_set_name,
16219                vec_len (locator_set_name));
16220   clib_memcpy (mp->key, key, vec_len (key));
16221
16222   vec_free (locator_set_name);
16223   vec_free (key);
16224
16225   /* send it... */
16226   S (mp);
16227
16228   /* Wait for a reply... */
16229   W (ret);
16230   return ret;
16231 }
16232
16233 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16234
16235 static int
16236 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16237 {
16238   u32 dp_table = 0, vni = 0;;
16239   unformat_input_t *input = vam->input;
16240   vl_api_gpe_add_del_fwd_entry_t *mp;
16241   u8 is_add = 1;
16242   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16243   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16244   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16245   u32 action = ~0, w;
16246   ip4_address_t rmt_rloc4, lcl_rloc4;
16247   ip6_address_t rmt_rloc6, lcl_rloc6;
16248   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16249   int ret;
16250
16251   memset (&rloc, 0, sizeof (rloc));
16252
16253   /* Parse args required to build the message */
16254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16255     {
16256       if (unformat (input, "del"))
16257         is_add = 0;
16258       else if (unformat (input, "add"))
16259         is_add = 1;
16260       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16261         {
16262           rmt_eid_set = 1;
16263         }
16264       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16265         {
16266           lcl_eid_set = 1;
16267         }
16268       else if (unformat (input, "vrf %d", &dp_table))
16269         ;
16270       else if (unformat (input, "bd %d", &dp_table))
16271         ;
16272       else if (unformat (input, "vni %d", &vni))
16273         ;
16274       else if (unformat (input, "w %d", &w))
16275         {
16276           if (!curr_rloc)
16277             {
16278               errmsg ("No RLOC configured for setting priority/weight!");
16279               return -99;
16280             }
16281           curr_rloc->weight = w;
16282         }
16283       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16284                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16285         {
16286           rloc.is_ip4 = 1;
16287
16288           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16289           rloc.weight = 0;
16290           vec_add1 (lcl_locs, rloc);
16291
16292           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16293           vec_add1 (rmt_locs, rloc);
16294           /* weight saved in rmt loc */
16295           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16296         }
16297       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16298                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16299         {
16300           rloc.is_ip4 = 0;
16301           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16302           rloc.weight = 0;
16303           vec_add1 (lcl_locs, rloc);
16304
16305           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16306           vec_add1 (rmt_locs, rloc);
16307           /* weight saved in rmt loc */
16308           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16309         }
16310       else if (unformat (input, "action %d", &action))
16311         {
16312           ;
16313         }
16314       else
16315         {
16316           clib_warning ("parse error '%U'", format_unformat_error, input);
16317           return -99;
16318         }
16319     }
16320
16321   if (!rmt_eid_set)
16322     {
16323       errmsg ("remote eid addresses not set");
16324       return -99;
16325     }
16326
16327   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16328     {
16329       errmsg ("eid types don't match");
16330       return -99;
16331     }
16332
16333   if (0 == rmt_locs && (u32) ~ 0 == action)
16334     {
16335       errmsg ("action not set for negative mapping");
16336       return -99;
16337     }
16338
16339   /* Construct the API message */
16340   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16341       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16342
16343   mp->is_add = is_add;
16344   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16345   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16346   mp->eid_type = rmt_eid->type;
16347   mp->dp_table = clib_host_to_net_u32 (dp_table);
16348   mp->vni = clib_host_to_net_u32 (vni);
16349   mp->rmt_len = rmt_eid->len;
16350   mp->lcl_len = lcl_eid->len;
16351   mp->action = action;
16352
16353   if (0 != rmt_locs && 0 != lcl_locs)
16354     {
16355       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16356       clib_memcpy (mp->locs, lcl_locs,
16357                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16358
16359       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16360       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16361                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16362     }
16363   vec_free (lcl_locs);
16364   vec_free (rmt_locs);
16365
16366   /* send it... */
16367   S (mp);
16368
16369   /* Wait for a reply... */
16370   W (ret);
16371   return ret;
16372 }
16373
16374 static int
16375 api_one_add_del_map_server (vat_main_t * vam)
16376 {
16377   unformat_input_t *input = vam->input;
16378   vl_api_one_add_del_map_server_t *mp;
16379   u8 is_add = 1;
16380   u8 ipv4_set = 0;
16381   u8 ipv6_set = 0;
16382   ip4_address_t ipv4;
16383   ip6_address_t ipv6;
16384   int ret;
16385
16386   /* Parse args required to build the message */
16387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16388     {
16389       if (unformat (input, "del"))
16390         {
16391           is_add = 0;
16392         }
16393       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16394         {
16395           ipv4_set = 1;
16396         }
16397       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16398         {
16399           ipv6_set = 1;
16400         }
16401       else
16402         break;
16403     }
16404
16405   if (ipv4_set && ipv6_set)
16406     {
16407       errmsg ("both eid v4 and v6 addresses set");
16408       return -99;
16409     }
16410
16411   if (!ipv4_set && !ipv6_set)
16412     {
16413       errmsg ("eid addresses not set");
16414       return -99;
16415     }
16416
16417   /* Construct the API message */
16418   M (ONE_ADD_DEL_MAP_SERVER, mp);
16419
16420   mp->is_add = is_add;
16421   if (ipv6_set)
16422     {
16423       mp->is_ipv6 = 1;
16424       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16425     }
16426   else
16427     {
16428       mp->is_ipv6 = 0;
16429       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16430     }
16431
16432   /* send it... */
16433   S (mp);
16434
16435   /* Wait for a reply... */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 #define api_lisp_add_del_map_server api_one_add_del_map_server
16441
16442 static int
16443 api_one_add_del_map_resolver (vat_main_t * vam)
16444 {
16445   unformat_input_t *input = vam->input;
16446   vl_api_one_add_del_map_resolver_t *mp;
16447   u8 is_add = 1;
16448   u8 ipv4_set = 0;
16449   u8 ipv6_set = 0;
16450   ip4_address_t ipv4;
16451   ip6_address_t ipv6;
16452   int ret;
16453
16454   /* Parse args required to build the message */
16455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16456     {
16457       if (unformat (input, "del"))
16458         {
16459           is_add = 0;
16460         }
16461       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16462         {
16463           ipv4_set = 1;
16464         }
16465       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16466         {
16467           ipv6_set = 1;
16468         }
16469       else
16470         break;
16471     }
16472
16473   if (ipv4_set && ipv6_set)
16474     {
16475       errmsg ("both eid v4 and v6 addresses set");
16476       return -99;
16477     }
16478
16479   if (!ipv4_set && !ipv6_set)
16480     {
16481       errmsg ("eid addresses not set");
16482       return -99;
16483     }
16484
16485   /* Construct the API message */
16486   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16487
16488   mp->is_add = is_add;
16489   if (ipv6_set)
16490     {
16491       mp->is_ipv6 = 1;
16492       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16493     }
16494   else
16495     {
16496       mp->is_ipv6 = 0;
16497       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16498     }
16499
16500   /* send it... */
16501   S (mp);
16502
16503   /* Wait for a reply... */
16504   W (ret);
16505   return ret;
16506 }
16507
16508 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16509
16510 static int
16511 api_lisp_gpe_enable_disable (vat_main_t * vam)
16512 {
16513   unformat_input_t *input = vam->input;
16514   vl_api_gpe_enable_disable_t *mp;
16515   u8 is_set = 0;
16516   u8 is_en = 1;
16517   int ret;
16518
16519   /* Parse args required to build the message */
16520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16521     {
16522       if (unformat (input, "enable"))
16523         {
16524           is_set = 1;
16525           is_en = 1;
16526         }
16527       else if (unformat (input, "disable"))
16528         {
16529           is_set = 1;
16530           is_en = 0;
16531         }
16532       else
16533         break;
16534     }
16535
16536   if (is_set == 0)
16537     {
16538       errmsg ("Value not set");
16539       return -99;
16540     }
16541
16542   /* Construct the API message */
16543   M (GPE_ENABLE_DISABLE, mp);
16544
16545   mp->is_en = is_en;
16546
16547   /* send it... */
16548   S (mp);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 static int
16556 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16557 {
16558   unformat_input_t *input = vam->input;
16559   vl_api_one_rloc_probe_enable_disable_t *mp;
16560   u8 is_set = 0;
16561   u8 is_en = 0;
16562   int ret;
16563
16564   /* Parse args required to build the message */
16565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16566     {
16567       if (unformat (input, "enable"))
16568         {
16569           is_set = 1;
16570           is_en = 1;
16571         }
16572       else if (unformat (input, "disable"))
16573         is_set = 1;
16574       else
16575         break;
16576     }
16577
16578   if (!is_set)
16579     {
16580       errmsg ("Value not set");
16581       return -99;
16582     }
16583
16584   /* Construct the API message */
16585   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16586
16587   mp->is_enabled = is_en;
16588
16589   /* send it... */
16590   S (mp);
16591
16592   /* Wait for a reply... */
16593   W (ret);
16594   return ret;
16595 }
16596
16597 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16598
16599 static int
16600 api_one_map_register_enable_disable (vat_main_t * vam)
16601 {
16602   unformat_input_t *input = vam->input;
16603   vl_api_one_map_register_enable_disable_t *mp;
16604   u8 is_set = 0;
16605   u8 is_en = 0;
16606   int ret;
16607
16608   /* Parse args required to build the message */
16609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16610     {
16611       if (unformat (input, "enable"))
16612         {
16613           is_set = 1;
16614           is_en = 1;
16615         }
16616       else if (unformat (input, "disable"))
16617         is_set = 1;
16618       else
16619         break;
16620     }
16621
16622   if (!is_set)
16623     {
16624       errmsg ("Value not set");
16625       return -99;
16626     }
16627
16628   /* Construct the API message */
16629   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16630
16631   mp->is_enabled = is_en;
16632
16633   /* send it... */
16634   S (mp);
16635
16636   /* Wait for a reply... */
16637   W (ret);
16638   return ret;
16639 }
16640
16641 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16642
16643 static int
16644 api_one_enable_disable (vat_main_t * vam)
16645 {
16646   unformat_input_t *input = vam->input;
16647   vl_api_one_enable_disable_t *mp;
16648   u8 is_set = 0;
16649   u8 is_en = 0;
16650   int ret;
16651
16652   /* Parse args required to build the message */
16653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16654     {
16655       if (unformat (input, "enable"))
16656         {
16657           is_set = 1;
16658           is_en = 1;
16659         }
16660       else if (unformat (input, "disable"))
16661         {
16662           is_set = 1;
16663         }
16664       else
16665         break;
16666     }
16667
16668   if (!is_set)
16669     {
16670       errmsg ("Value not set");
16671       return -99;
16672     }
16673
16674   /* Construct the API message */
16675   M (ONE_ENABLE_DISABLE, mp);
16676
16677   mp->is_en = is_en;
16678
16679   /* send it... */
16680   S (mp);
16681
16682   /* Wait for a reply... */
16683   W (ret);
16684   return ret;
16685 }
16686
16687 #define api_lisp_enable_disable api_one_enable_disable
16688
16689 static int
16690 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16691 {
16692   unformat_input_t *input = vam->input;
16693   vl_api_one_enable_disable_xtr_mode_t *mp;
16694   u8 is_set = 0;
16695   u8 is_en = 0;
16696   int ret;
16697
16698   /* Parse args required to build the message */
16699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (input, "enable"))
16702         {
16703           is_set = 1;
16704           is_en = 1;
16705         }
16706       else if (unformat (input, "disable"))
16707         {
16708           is_set = 1;
16709         }
16710       else
16711         break;
16712     }
16713
16714   if (!is_set)
16715     {
16716       errmsg ("Value not set");
16717       return -99;
16718     }
16719
16720   /* Construct the API message */
16721   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16722
16723   mp->is_en = is_en;
16724
16725   /* send it... */
16726   S (mp);
16727
16728   /* Wait for a reply... */
16729   W (ret);
16730   return ret;
16731 }
16732
16733 static int
16734 api_one_show_xtr_mode (vat_main_t * vam)
16735 {
16736   vl_api_one_show_xtr_mode_t *mp;
16737   int ret;
16738
16739   /* Construct the API message */
16740   M (ONE_SHOW_XTR_MODE, mp);
16741
16742   /* send it... */
16743   S (mp);
16744
16745   /* Wait for a reply... */
16746   W (ret);
16747   return ret;
16748 }
16749
16750 static int
16751 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16752 {
16753   unformat_input_t *input = vam->input;
16754   vl_api_one_enable_disable_pitr_mode_t *mp;
16755   u8 is_set = 0;
16756   u8 is_en = 0;
16757   int ret;
16758
16759   /* Parse args required to build the message */
16760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16761     {
16762       if (unformat (input, "enable"))
16763         {
16764           is_set = 1;
16765           is_en = 1;
16766         }
16767       else if (unformat (input, "disable"))
16768         {
16769           is_set = 1;
16770         }
16771       else
16772         break;
16773     }
16774
16775   if (!is_set)
16776     {
16777       errmsg ("Value not set");
16778       return -99;
16779     }
16780
16781   /* Construct the API message */
16782   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16783
16784   mp->is_en = is_en;
16785
16786   /* send it... */
16787   S (mp);
16788
16789   /* Wait for a reply... */
16790   W (ret);
16791   return ret;
16792 }
16793
16794 static int
16795 api_one_show_pitr_mode (vat_main_t * vam)
16796 {
16797   vl_api_one_show_pitr_mode_t *mp;
16798   int ret;
16799
16800   /* Construct the API message */
16801   M (ONE_SHOW_PITR_MODE, mp);
16802
16803   /* send it... */
16804   S (mp);
16805
16806   /* Wait for a reply... */
16807   W (ret);
16808   return ret;
16809 }
16810
16811 static int
16812 api_one_enable_disable_petr_mode (vat_main_t * vam)
16813 {
16814   unformat_input_t *input = vam->input;
16815   vl_api_one_enable_disable_petr_mode_t *mp;
16816   u8 is_set = 0;
16817   u8 is_en = 0;
16818   int ret;
16819
16820   /* Parse args required to build the message */
16821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16822     {
16823       if (unformat (input, "enable"))
16824         {
16825           is_set = 1;
16826           is_en = 1;
16827         }
16828       else if (unformat (input, "disable"))
16829         {
16830           is_set = 1;
16831         }
16832       else
16833         break;
16834     }
16835
16836   if (!is_set)
16837     {
16838       errmsg ("Value not set");
16839       return -99;
16840     }
16841
16842   /* Construct the API message */
16843   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16844
16845   mp->is_en = is_en;
16846
16847   /* send it... */
16848   S (mp);
16849
16850   /* Wait for a reply... */
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_one_show_petr_mode (vat_main_t * vam)
16857 {
16858   vl_api_one_show_petr_mode_t *mp;
16859   int ret;
16860
16861   /* Construct the API message */
16862   M (ONE_SHOW_PETR_MODE, mp);
16863
16864   /* send it... */
16865   S (mp);
16866
16867   /* Wait for a reply... */
16868   W (ret);
16869   return ret;
16870 }
16871
16872 static int
16873 api_show_one_map_register_state (vat_main_t * vam)
16874 {
16875   vl_api_show_one_map_register_state_t *mp;
16876   int ret;
16877
16878   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16879
16880   /* send */
16881   S (mp);
16882
16883   /* wait for reply */
16884   W (ret);
16885   return ret;
16886 }
16887
16888 #define api_show_lisp_map_register_state api_show_one_map_register_state
16889
16890 static int
16891 api_show_one_rloc_probe_state (vat_main_t * vam)
16892 {
16893   vl_api_show_one_rloc_probe_state_t *mp;
16894   int ret;
16895
16896   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16897
16898   /* send */
16899   S (mp);
16900
16901   /* wait for reply */
16902   W (ret);
16903   return ret;
16904 }
16905
16906 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16907
16908 static int
16909 api_one_add_del_ndp_entry (vat_main_t * vam)
16910 {
16911   vl_api_one_add_del_ndp_entry_t *mp;
16912   unformat_input_t *input = vam->input;
16913   u8 is_add = 1;
16914   u8 mac_set = 0;
16915   u8 bd_set = 0;
16916   u8 ip_set = 0;
16917   u8 mac[6] = { 0, };
16918   u8 ip6[16] = { 0, };
16919   u32 bd = ~0;
16920   int ret;
16921
16922   /* Parse args required to build the message */
16923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16924     {
16925       if (unformat (input, "del"))
16926         is_add = 0;
16927       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16928         mac_set = 1;
16929       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16930         ip_set = 1;
16931       else if (unformat (input, "bd %d", &bd))
16932         bd_set = 1;
16933       else
16934         {
16935           errmsg ("parse error '%U'", format_unformat_error, input);
16936           return -99;
16937         }
16938     }
16939
16940   if (!bd_set || !ip_set || (!mac_set && is_add))
16941     {
16942       errmsg ("Missing BD, IP or MAC!");
16943       return -99;
16944     }
16945
16946   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16947   mp->is_add = is_add;
16948   clib_memcpy (mp->mac, mac, 6);
16949   mp->bd = clib_host_to_net_u32 (bd);
16950   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16951
16952   /* send */
16953   S (mp);
16954
16955   /* wait for reply */
16956   W (ret);
16957   return ret;
16958 }
16959
16960 static int
16961 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16962 {
16963   vl_api_one_add_del_l2_arp_entry_t *mp;
16964   unformat_input_t *input = vam->input;
16965   u8 is_add = 1;
16966   u8 mac_set = 0;
16967   u8 bd_set = 0;
16968   u8 ip_set = 0;
16969   u8 mac[6] = { 0, };
16970   u32 ip4 = 0, bd = ~0;
16971   int ret;
16972
16973   /* Parse args required to build the message */
16974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16975     {
16976       if (unformat (input, "del"))
16977         is_add = 0;
16978       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16979         mac_set = 1;
16980       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16981         ip_set = 1;
16982       else if (unformat (input, "bd %d", &bd))
16983         bd_set = 1;
16984       else
16985         {
16986           errmsg ("parse error '%U'", format_unformat_error, input);
16987           return -99;
16988         }
16989     }
16990
16991   if (!bd_set || !ip_set || (!mac_set && is_add))
16992     {
16993       errmsg ("Missing BD, IP or MAC!");
16994       return -99;
16995     }
16996
16997   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16998   mp->is_add = is_add;
16999   clib_memcpy (mp->mac, mac, 6);
17000   mp->bd = clib_host_to_net_u32 (bd);
17001   mp->ip4 = ip4;
17002
17003   /* send */
17004   S (mp);
17005
17006   /* wait for reply */
17007   W (ret);
17008   return ret;
17009 }
17010
17011 static int
17012 api_one_ndp_bd_get (vat_main_t * vam)
17013 {
17014   vl_api_one_ndp_bd_get_t *mp;
17015   int ret;
17016
17017   M (ONE_NDP_BD_GET, mp);
17018
17019   /* send */
17020   S (mp);
17021
17022   /* wait for reply */
17023   W (ret);
17024   return ret;
17025 }
17026
17027 static int
17028 api_one_ndp_entries_get (vat_main_t * vam)
17029 {
17030   vl_api_one_ndp_entries_get_t *mp;
17031   unformat_input_t *input = vam->input;
17032   u8 bd_set = 0;
17033   u32 bd = ~0;
17034   int ret;
17035
17036   /* Parse args required to build the message */
17037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17038     {
17039       if (unformat (input, "bd %d", &bd))
17040         bd_set = 1;
17041       else
17042         {
17043           errmsg ("parse error '%U'", format_unformat_error, input);
17044           return -99;
17045         }
17046     }
17047
17048   if (!bd_set)
17049     {
17050       errmsg ("Expected bridge domain!");
17051       return -99;
17052     }
17053
17054   M (ONE_NDP_ENTRIES_GET, mp);
17055   mp->bd = clib_host_to_net_u32 (bd);
17056
17057   /* send */
17058   S (mp);
17059
17060   /* wait for reply */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_one_l2_arp_bd_get (vat_main_t * vam)
17067 {
17068   vl_api_one_l2_arp_bd_get_t *mp;
17069   int ret;
17070
17071   M (ONE_L2_ARP_BD_GET, mp);
17072
17073   /* send */
17074   S (mp);
17075
17076   /* wait for reply */
17077   W (ret);
17078   return ret;
17079 }
17080
17081 static int
17082 api_one_l2_arp_entries_get (vat_main_t * vam)
17083 {
17084   vl_api_one_l2_arp_entries_get_t *mp;
17085   unformat_input_t *input = vam->input;
17086   u8 bd_set = 0;
17087   u32 bd = ~0;
17088   int ret;
17089
17090   /* Parse args required to build the message */
17091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17092     {
17093       if (unformat (input, "bd %d", &bd))
17094         bd_set = 1;
17095       else
17096         {
17097           errmsg ("parse error '%U'", format_unformat_error, input);
17098           return -99;
17099         }
17100     }
17101
17102   if (!bd_set)
17103     {
17104       errmsg ("Expected bridge domain!");
17105       return -99;
17106     }
17107
17108   M (ONE_L2_ARP_ENTRIES_GET, mp);
17109   mp->bd = clib_host_to_net_u32 (bd);
17110
17111   /* send */
17112   S (mp);
17113
17114   /* wait for reply */
17115   W (ret);
17116   return ret;
17117 }
17118
17119 static int
17120 api_one_stats_enable_disable (vat_main_t * vam)
17121 {
17122   vl_api_one_stats_enable_disable_t *mp;
17123   unformat_input_t *input = vam->input;
17124   u8 is_set = 0;
17125   u8 is_en = 0;
17126   int ret;
17127
17128   /* Parse args required to build the message */
17129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (input, "enable"))
17132         {
17133           is_set = 1;
17134           is_en = 1;
17135         }
17136       else if (unformat (input, "disable"))
17137         {
17138           is_set = 1;
17139         }
17140       else
17141         break;
17142     }
17143
17144   if (!is_set)
17145     {
17146       errmsg ("Value not set");
17147       return -99;
17148     }
17149
17150   M (ONE_STATS_ENABLE_DISABLE, mp);
17151   mp->is_en = is_en;
17152
17153   /* send */
17154   S (mp);
17155
17156   /* wait for reply */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static int
17162 api_show_one_stats_enable_disable (vat_main_t * vam)
17163 {
17164   vl_api_show_one_stats_enable_disable_t *mp;
17165   int ret;
17166
17167   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17168
17169   /* send */
17170   S (mp);
17171
17172   /* wait for reply */
17173   W (ret);
17174   return ret;
17175 }
17176
17177 static int
17178 api_show_one_map_request_mode (vat_main_t * vam)
17179 {
17180   vl_api_show_one_map_request_mode_t *mp;
17181   int ret;
17182
17183   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17184
17185   /* send */
17186   S (mp);
17187
17188   /* wait for reply */
17189   W (ret);
17190   return ret;
17191 }
17192
17193 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17194
17195 static int
17196 api_one_map_request_mode (vat_main_t * vam)
17197 {
17198   unformat_input_t *input = vam->input;
17199   vl_api_one_map_request_mode_t *mp;
17200   u8 mode = 0;
17201   int ret;
17202
17203   /* Parse args required to build the message */
17204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17205     {
17206       if (unformat (input, "dst-only"))
17207         mode = 0;
17208       else if (unformat (input, "src-dst"))
17209         mode = 1;
17210       else
17211         {
17212           errmsg ("parse error '%U'", format_unformat_error, input);
17213           return -99;
17214         }
17215     }
17216
17217   M (ONE_MAP_REQUEST_MODE, mp);
17218
17219   mp->mode = mode;
17220
17221   /* send */
17222   S (mp);
17223
17224   /* wait for reply */
17225   W (ret);
17226   return ret;
17227 }
17228
17229 #define api_lisp_map_request_mode api_one_map_request_mode
17230
17231 /**
17232  * Enable/disable ONE proxy ITR.
17233  *
17234  * @param vam vpp API test context
17235  * @return return code
17236  */
17237 static int
17238 api_one_pitr_set_locator_set (vat_main_t * vam)
17239 {
17240   u8 ls_name_set = 0;
17241   unformat_input_t *input = vam->input;
17242   vl_api_one_pitr_set_locator_set_t *mp;
17243   u8 is_add = 1;
17244   u8 *ls_name = 0;
17245   int ret;
17246
17247   /* Parse args required to build the message */
17248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17249     {
17250       if (unformat (input, "del"))
17251         is_add = 0;
17252       else if (unformat (input, "locator-set %s", &ls_name))
17253         ls_name_set = 1;
17254       else
17255         {
17256           errmsg ("parse error '%U'", format_unformat_error, input);
17257           return -99;
17258         }
17259     }
17260
17261   if (!ls_name_set)
17262     {
17263       errmsg ("locator-set name not set!");
17264       return -99;
17265     }
17266
17267   M (ONE_PITR_SET_LOCATOR_SET, mp);
17268
17269   mp->is_add = is_add;
17270   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17271   vec_free (ls_name);
17272
17273   /* send */
17274   S (mp);
17275
17276   /* wait for reply */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17282
17283 static int
17284 api_one_nsh_set_locator_set (vat_main_t * vam)
17285 {
17286   u8 ls_name_set = 0;
17287   unformat_input_t *input = vam->input;
17288   vl_api_one_nsh_set_locator_set_t *mp;
17289   u8 is_add = 1;
17290   u8 *ls_name = 0;
17291   int ret;
17292
17293   /* Parse args required to build the message */
17294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17295     {
17296       if (unformat (input, "del"))
17297         is_add = 0;
17298       else if (unformat (input, "ls %s", &ls_name))
17299         ls_name_set = 1;
17300       else
17301         {
17302           errmsg ("parse error '%U'", format_unformat_error, input);
17303           return -99;
17304         }
17305     }
17306
17307   if (!ls_name_set && is_add)
17308     {
17309       errmsg ("locator-set name not set!");
17310       return -99;
17311     }
17312
17313   M (ONE_NSH_SET_LOCATOR_SET, mp);
17314
17315   mp->is_add = is_add;
17316   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17317   vec_free (ls_name);
17318
17319   /* send */
17320   S (mp);
17321
17322   /* wait for reply */
17323   W (ret);
17324   return ret;
17325 }
17326
17327 static int
17328 api_show_one_pitr (vat_main_t * vam)
17329 {
17330   vl_api_show_one_pitr_t *mp;
17331   int ret;
17332
17333   if (!vam->json_output)
17334     {
17335       print (vam->ofp, "%=20s", "lisp status:");
17336     }
17337
17338   M (SHOW_ONE_PITR, mp);
17339   /* send it... */
17340   S (mp);
17341
17342   /* Wait for a reply... */
17343   W (ret);
17344   return ret;
17345 }
17346
17347 #define api_show_lisp_pitr api_show_one_pitr
17348
17349 static int
17350 api_one_use_petr (vat_main_t * vam)
17351 {
17352   unformat_input_t *input = vam->input;
17353   vl_api_one_use_petr_t *mp;
17354   u8 is_add = 0;
17355   ip_address_t ip;
17356   int ret;
17357
17358   memset (&ip, 0, sizeof (ip));
17359
17360   /* Parse args required to build the message */
17361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17362     {
17363       if (unformat (input, "disable"))
17364         is_add = 0;
17365       else
17366         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17367         {
17368           is_add = 1;
17369           ip_addr_version (&ip) = IP4;
17370         }
17371       else
17372         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17373         {
17374           is_add = 1;
17375           ip_addr_version (&ip) = IP6;
17376         }
17377       else
17378         {
17379           errmsg ("parse error '%U'", format_unformat_error, input);
17380           return -99;
17381         }
17382     }
17383
17384   M (ONE_USE_PETR, mp);
17385
17386   mp->is_add = is_add;
17387   if (is_add)
17388     {
17389       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17390       if (mp->is_ip4)
17391         clib_memcpy (mp->address, &ip, 4);
17392       else
17393         clib_memcpy (mp->address, &ip, 16);
17394     }
17395
17396   /* send */
17397   S (mp);
17398
17399   /* wait for reply */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 #define api_lisp_use_petr api_one_use_petr
17405
17406 static int
17407 api_show_one_nsh_mapping (vat_main_t * vam)
17408 {
17409   vl_api_show_one_use_petr_t *mp;
17410   int ret;
17411
17412   if (!vam->json_output)
17413     {
17414       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17415     }
17416
17417   M (SHOW_ONE_NSH_MAPPING, mp);
17418   /* send it... */
17419   S (mp);
17420
17421   /* Wait for a reply... */
17422   W (ret);
17423   return ret;
17424 }
17425
17426 static int
17427 api_show_one_use_petr (vat_main_t * vam)
17428 {
17429   vl_api_show_one_use_petr_t *mp;
17430   int ret;
17431
17432   if (!vam->json_output)
17433     {
17434       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17435     }
17436
17437   M (SHOW_ONE_USE_PETR, mp);
17438   /* send it... */
17439   S (mp);
17440
17441   /* Wait for a reply... */
17442   W (ret);
17443   return ret;
17444 }
17445
17446 #define api_show_lisp_use_petr api_show_one_use_petr
17447
17448 /**
17449  * Add/delete mapping between vni and vrf
17450  */
17451 static int
17452 api_one_eid_table_add_del_map (vat_main_t * vam)
17453 {
17454   unformat_input_t *input = vam->input;
17455   vl_api_one_eid_table_add_del_map_t *mp;
17456   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17457   u32 vni, vrf, bd_index;
17458   int ret;
17459
17460   /* Parse args required to build the message */
17461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17462     {
17463       if (unformat (input, "del"))
17464         is_add = 0;
17465       else if (unformat (input, "vrf %d", &vrf))
17466         vrf_set = 1;
17467       else if (unformat (input, "bd_index %d", &bd_index))
17468         bd_index_set = 1;
17469       else if (unformat (input, "vni %d", &vni))
17470         vni_set = 1;
17471       else
17472         break;
17473     }
17474
17475   if (!vni_set || (!vrf_set && !bd_index_set))
17476     {
17477       errmsg ("missing arguments!");
17478       return -99;
17479     }
17480
17481   if (vrf_set && bd_index_set)
17482     {
17483       errmsg ("error: both vrf and bd entered!");
17484       return -99;
17485     }
17486
17487   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17488
17489   mp->is_add = is_add;
17490   mp->vni = htonl (vni);
17491   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17492   mp->is_l2 = bd_index_set;
17493
17494   /* send */
17495   S (mp);
17496
17497   /* wait for reply */
17498   W (ret);
17499   return ret;
17500 }
17501
17502 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17503
17504 uword
17505 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17506 {
17507   u32 *action = va_arg (*args, u32 *);
17508   u8 *s = 0;
17509
17510   if (unformat (input, "%s", &s))
17511     {
17512       if (!strcmp ((char *) s, "no-action"))
17513         action[0] = 0;
17514       else if (!strcmp ((char *) s, "natively-forward"))
17515         action[0] = 1;
17516       else if (!strcmp ((char *) s, "send-map-request"))
17517         action[0] = 2;
17518       else if (!strcmp ((char *) s, "drop"))
17519         action[0] = 3;
17520       else
17521         {
17522           clib_warning ("invalid action: '%s'", s);
17523           action[0] = 3;
17524         }
17525     }
17526   else
17527     return 0;
17528
17529   vec_free (s);
17530   return 1;
17531 }
17532
17533 /**
17534  * Add/del remote mapping to/from ONE control plane
17535  *
17536  * @param vam vpp API test context
17537  * @return return code
17538  */
17539 static int
17540 api_one_add_del_remote_mapping (vat_main_t * vam)
17541 {
17542   unformat_input_t *input = vam->input;
17543   vl_api_one_add_del_remote_mapping_t *mp;
17544   u32 vni = 0;
17545   lisp_eid_vat_t _eid, *eid = &_eid;
17546   lisp_eid_vat_t _seid, *seid = &_seid;
17547   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17548   u32 action = ~0, p, w, data_len;
17549   ip4_address_t rloc4;
17550   ip6_address_t rloc6;
17551   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17552   int ret;
17553
17554   memset (&rloc, 0, sizeof (rloc));
17555
17556   /* Parse args required to build the message */
17557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17558     {
17559       if (unformat (input, "del-all"))
17560         {
17561           del_all = 1;
17562         }
17563       else if (unformat (input, "del"))
17564         {
17565           is_add = 0;
17566         }
17567       else if (unformat (input, "add"))
17568         {
17569           is_add = 1;
17570         }
17571       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17572         {
17573           eid_set = 1;
17574         }
17575       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17576         {
17577           seid_set = 1;
17578         }
17579       else if (unformat (input, "vni %d", &vni))
17580         {
17581           ;
17582         }
17583       else if (unformat (input, "p %d w %d", &p, &w))
17584         {
17585           if (!curr_rloc)
17586             {
17587               errmsg ("No RLOC configured for setting priority/weight!");
17588               return -99;
17589             }
17590           curr_rloc->priority = p;
17591           curr_rloc->weight = w;
17592         }
17593       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17594         {
17595           rloc.is_ip4 = 1;
17596           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17597           vec_add1 (rlocs, rloc);
17598           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17599         }
17600       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17601         {
17602           rloc.is_ip4 = 0;
17603           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17604           vec_add1 (rlocs, rloc);
17605           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17606         }
17607       else if (unformat (input, "action %U",
17608                          unformat_negative_mapping_action, &action))
17609         {
17610           ;
17611         }
17612       else
17613         {
17614           clib_warning ("parse error '%U'", format_unformat_error, input);
17615           return -99;
17616         }
17617     }
17618
17619   if (0 == eid_set)
17620     {
17621       errmsg ("missing params!");
17622       return -99;
17623     }
17624
17625   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17626     {
17627       errmsg ("no action set for negative map-reply!");
17628       return -99;
17629     }
17630
17631   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17632
17633   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17634   mp->is_add = is_add;
17635   mp->vni = htonl (vni);
17636   mp->action = (u8) action;
17637   mp->is_src_dst = seid_set;
17638   mp->eid_len = eid->len;
17639   mp->seid_len = seid->len;
17640   mp->del_all = del_all;
17641   mp->eid_type = eid->type;
17642   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17643   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17644
17645   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17646   clib_memcpy (mp->rlocs, rlocs, data_len);
17647   vec_free (rlocs);
17648
17649   /* send it... */
17650   S (mp);
17651
17652   /* Wait for a reply... */
17653   W (ret);
17654   return ret;
17655 }
17656
17657 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17658
17659 /**
17660  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17661  * forwarding entries in data-plane accordingly.
17662  *
17663  * @param vam vpp API test context
17664  * @return return code
17665  */
17666 static int
17667 api_one_add_del_adjacency (vat_main_t * vam)
17668 {
17669   unformat_input_t *input = vam->input;
17670   vl_api_one_add_del_adjacency_t *mp;
17671   u32 vni = 0;
17672   ip4_address_t leid4, reid4;
17673   ip6_address_t leid6, reid6;
17674   u8 reid_mac[6] = { 0 };
17675   u8 leid_mac[6] = { 0 };
17676   u8 reid_type, leid_type;
17677   u32 leid_len = 0, reid_len = 0, len;
17678   u8 is_add = 1;
17679   int ret;
17680
17681   leid_type = reid_type = (u8) ~ 0;
17682
17683   /* Parse args required to build the message */
17684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17685     {
17686       if (unformat (input, "del"))
17687         {
17688           is_add = 0;
17689         }
17690       else if (unformat (input, "add"))
17691         {
17692           is_add = 1;
17693         }
17694       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17695                          &reid4, &len))
17696         {
17697           reid_type = 0;        /* ipv4 */
17698           reid_len = len;
17699         }
17700       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17701                          &reid6, &len))
17702         {
17703           reid_type = 1;        /* ipv6 */
17704           reid_len = len;
17705         }
17706       else if (unformat (input, "reid %U", unformat_ethernet_address,
17707                          reid_mac))
17708         {
17709           reid_type = 2;        /* mac */
17710         }
17711       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17712                          &leid4, &len))
17713         {
17714           leid_type = 0;        /* ipv4 */
17715           leid_len = len;
17716         }
17717       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17718                          &leid6, &len))
17719         {
17720           leid_type = 1;        /* ipv6 */
17721           leid_len = len;
17722         }
17723       else if (unformat (input, "leid %U", unformat_ethernet_address,
17724                          leid_mac))
17725         {
17726           leid_type = 2;        /* mac */
17727         }
17728       else if (unformat (input, "vni %d", &vni))
17729         {
17730           ;
17731         }
17732       else
17733         {
17734           errmsg ("parse error '%U'", format_unformat_error, input);
17735           return -99;
17736         }
17737     }
17738
17739   if ((u8) ~ 0 == reid_type)
17740     {
17741       errmsg ("missing params!");
17742       return -99;
17743     }
17744
17745   if (leid_type != reid_type)
17746     {
17747       errmsg ("remote and local EIDs are of different types!");
17748       return -99;
17749     }
17750
17751   M (ONE_ADD_DEL_ADJACENCY, mp);
17752   mp->is_add = is_add;
17753   mp->vni = htonl (vni);
17754   mp->leid_len = leid_len;
17755   mp->reid_len = reid_len;
17756   mp->eid_type = reid_type;
17757
17758   switch (mp->eid_type)
17759     {
17760     case 0:
17761       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17762       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17763       break;
17764     case 1:
17765       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17766       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17767       break;
17768     case 2:
17769       clib_memcpy (mp->leid, leid_mac, 6);
17770       clib_memcpy (mp->reid, reid_mac, 6);
17771       break;
17772     default:
17773       errmsg ("unknown EID type %d!", mp->eid_type);
17774       return 0;
17775     }
17776
17777   /* send it... */
17778   S (mp);
17779
17780   /* Wait for a reply... */
17781   W (ret);
17782   return ret;
17783 }
17784
17785 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17786
17787 uword
17788 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17789 {
17790   u32 *mode = va_arg (*args, u32 *);
17791
17792   if (unformat (input, "lisp"))
17793     *mode = 0;
17794   else if (unformat (input, "vxlan"))
17795     *mode = 1;
17796   else
17797     return 0;
17798
17799   return 1;
17800 }
17801
17802 static int
17803 api_gpe_get_encap_mode (vat_main_t * vam)
17804 {
17805   vl_api_gpe_get_encap_mode_t *mp;
17806   int ret;
17807
17808   /* Construct the API message */
17809   M (GPE_GET_ENCAP_MODE, mp);
17810
17811   /* send it... */
17812   S (mp);
17813
17814   /* Wait for a reply... */
17815   W (ret);
17816   return ret;
17817 }
17818
17819 static int
17820 api_gpe_set_encap_mode (vat_main_t * vam)
17821 {
17822   unformat_input_t *input = vam->input;
17823   vl_api_gpe_set_encap_mode_t *mp;
17824   int ret;
17825   u32 mode = 0;
17826
17827   /* Parse args required to build the message */
17828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17829     {
17830       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17831         ;
17832       else
17833         break;
17834     }
17835
17836   /* Construct the API message */
17837   M (GPE_SET_ENCAP_MODE, mp);
17838
17839   mp->mode = mode;
17840
17841   /* send it... */
17842   S (mp);
17843
17844   /* Wait for a reply... */
17845   W (ret);
17846   return ret;
17847 }
17848
17849 static int
17850 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17851 {
17852   unformat_input_t *input = vam->input;
17853   vl_api_gpe_add_del_iface_t *mp;
17854   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17855   u32 dp_table = 0, vni = 0;
17856   int ret;
17857
17858   /* Parse args required to build the message */
17859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17860     {
17861       if (unformat (input, "up"))
17862         {
17863           action_set = 1;
17864           is_add = 1;
17865         }
17866       else if (unformat (input, "down"))
17867         {
17868           action_set = 1;
17869           is_add = 0;
17870         }
17871       else if (unformat (input, "table_id %d", &dp_table))
17872         {
17873           dp_table_set = 1;
17874         }
17875       else if (unformat (input, "bd_id %d", &dp_table))
17876         {
17877           dp_table_set = 1;
17878           is_l2 = 1;
17879         }
17880       else if (unformat (input, "vni %d", &vni))
17881         {
17882           vni_set = 1;
17883         }
17884       else
17885         break;
17886     }
17887
17888   if (action_set == 0)
17889     {
17890       errmsg ("Action not set");
17891       return -99;
17892     }
17893   if (dp_table_set == 0 || vni_set == 0)
17894     {
17895       errmsg ("vni and dp_table must be set");
17896       return -99;
17897     }
17898
17899   /* Construct the API message */
17900   M (GPE_ADD_DEL_IFACE, mp);
17901
17902   mp->is_add = is_add;
17903   mp->dp_table = clib_host_to_net_u32 (dp_table);
17904   mp->is_l2 = is_l2;
17905   mp->vni = clib_host_to_net_u32 (vni);
17906
17907   /* send it... */
17908   S (mp);
17909
17910   /* Wait for a reply... */
17911   W (ret);
17912   return ret;
17913 }
17914
17915 static int
17916 api_one_map_register_fallback_threshold (vat_main_t * vam)
17917 {
17918   unformat_input_t *input = vam->input;
17919   vl_api_one_map_register_fallback_threshold_t *mp;
17920   u32 value = 0;
17921   u8 is_set = 0;
17922   int ret;
17923
17924   /* Parse args required to build the message */
17925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17926     {
17927       if (unformat (input, "%u", &value))
17928         is_set = 1;
17929       else
17930         {
17931           clib_warning ("parse error '%U'", format_unformat_error, input);
17932           return -99;
17933         }
17934     }
17935
17936   if (!is_set)
17937     {
17938       errmsg ("fallback threshold value is missing!");
17939       return -99;
17940     }
17941
17942   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17943   mp->value = clib_host_to_net_u32 (value);
17944
17945   /* send it... */
17946   S (mp);
17947
17948   /* Wait for a reply... */
17949   W (ret);
17950   return ret;
17951 }
17952
17953 static int
17954 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17955 {
17956   vl_api_show_one_map_register_fallback_threshold_t *mp;
17957   int ret;
17958
17959   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17960
17961   /* send it... */
17962   S (mp);
17963
17964   /* Wait for a reply... */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 uword
17970 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17971 {
17972   u32 *proto = va_arg (*args, u32 *);
17973
17974   if (unformat (input, "udp"))
17975     *proto = 1;
17976   else if (unformat (input, "api"))
17977     *proto = 2;
17978   else
17979     return 0;
17980
17981   return 1;
17982 }
17983
17984 static int
17985 api_one_set_transport_protocol (vat_main_t * vam)
17986 {
17987   unformat_input_t *input = vam->input;
17988   vl_api_one_set_transport_protocol_t *mp;
17989   u8 is_set = 0;
17990   u32 protocol = 0;
17991   int ret;
17992
17993   /* Parse args required to build the message */
17994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17995     {
17996       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17997         is_set = 1;
17998       else
17999         {
18000           clib_warning ("parse error '%U'", format_unformat_error, input);
18001           return -99;
18002         }
18003     }
18004
18005   if (!is_set)
18006     {
18007       errmsg ("Transport protocol missing!");
18008       return -99;
18009     }
18010
18011   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18012   mp->protocol = (u8) protocol;
18013
18014   /* send it... */
18015   S (mp);
18016
18017   /* Wait for a reply... */
18018   W (ret);
18019   return ret;
18020 }
18021
18022 static int
18023 api_one_get_transport_protocol (vat_main_t * vam)
18024 {
18025   vl_api_one_get_transport_protocol_t *mp;
18026   int ret;
18027
18028   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18029
18030   /* send it... */
18031   S (mp);
18032
18033   /* Wait for a reply... */
18034   W (ret);
18035   return ret;
18036 }
18037
18038 static int
18039 api_one_map_register_set_ttl (vat_main_t * vam)
18040 {
18041   unformat_input_t *input = vam->input;
18042   vl_api_one_map_register_set_ttl_t *mp;
18043   u32 ttl = 0;
18044   u8 is_set = 0;
18045   int ret;
18046
18047   /* Parse args required to build the message */
18048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18049     {
18050       if (unformat (input, "%u", &ttl))
18051         is_set = 1;
18052       else
18053         {
18054           clib_warning ("parse error '%U'", format_unformat_error, input);
18055           return -99;
18056         }
18057     }
18058
18059   if (!is_set)
18060     {
18061       errmsg ("TTL value missing!");
18062       return -99;
18063     }
18064
18065   M (ONE_MAP_REGISTER_SET_TTL, mp);
18066   mp->ttl = clib_host_to_net_u32 (ttl);
18067
18068   /* send it... */
18069   S (mp);
18070
18071   /* Wait for a reply... */
18072   W (ret);
18073   return ret;
18074 }
18075
18076 static int
18077 api_show_one_map_register_ttl (vat_main_t * vam)
18078 {
18079   vl_api_show_one_map_register_ttl_t *mp;
18080   int ret;
18081
18082   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18083
18084   /* send it... */
18085   S (mp);
18086
18087   /* Wait for a reply... */
18088   W (ret);
18089   return ret;
18090 }
18091
18092 /**
18093  * Add/del map request itr rlocs from ONE control plane and updates
18094  *
18095  * @param vam vpp API test context
18096  * @return return code
18097  */
18098 static int
18099 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18100 {
18101   unformat_input_t *input = vam->input;
18102   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18103   u8 *locator_set_name = 0;
18104   u8 locator_set_name_set = 0;
18105   u8 is_add = 1;
18106   int ret;
18107
18108   /* Parse args required to build the message */
18109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18110     {
18111       if (unformat (input, "del"))
18112         {
18113           is_add = 0;
18114         }
18115       else if (unformat (input, "%_%v%_", &locator_set_name))
18116         {
18117           locator_set_name_set = 1;
18118         }
18119       else
18120         {
18121           clib_warning ("parse error '%U'", format_unformat_error, input);
18122           return -99;
18123         }
18124     }
18125
18126   if (is_add && !locator_set_name_set)
18127     {
18128       errmsg ("itr-rloc is not set!");
18129       return -99;
18130     }
18131
18132   if (is_add && vec_len (locator_set_name) > 64)
18133     {
18134       errmsg ("itr-rloc locator-set name too long");
18135       vec_free (locator_set_name);
18136       return -99;
18137     }
18138
18139   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18140   mp->is_add = is_add;
18141   if (is_add)
18142     {
18143       clib_memcpy (mp->locator_set_name, locator_set_name,
18144                    vec_len (locator_set_name));
18145     }
18146   else
18147     {
18148       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18149     }
18150   vec_free (locator_set_name);
18151
18152   /* send it... */
18153   S (mp);
18154
18155   /* Wait for a reply... */
18156   W (ret);
18157   return ret;
18158 }
18159
18160 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18161
18162 static int
18163 api_one_locator_dump (vat_main_t * vam)
18164 {
18165   unformat_input_t *input = vam->input;
18166   vl_api_one_locator_dump_t *mp;
18167   vl_api_control_ping_t *mp_ping;
18168   u8 is_index_set = 0, is_name_set = 0;
18169   u8 *ls_name = 0;
18170   u32 ls_index = ~0;
18171   int ret;
18172
18173   /* Parse args required to build the message */
18174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18175     {
18176       if (unformat (input, "ls_name %_%v%_", &ls_name))
18177         {
18178           is_name_set = 1;
18179         }
18180       else if (unformat (input, "ls_index %d", &ls_index))
18181         {
18182           is_index_set = 1;
18183         }
18184       else
18185         {
18186           errmsg ("parse error '%U'", format_unformat_error, input);
18187           return -99;
18188         }
18189     }
18190
18191   if (!is_index_set && !is_name_set)
18192     {
18193       errmsg ("error: expected one of index or name!");
18194       return -99;
18195     }
18196
18197   if (is_index_set && is_name_set)
18198     {
18199       errmsg ("error: only one param expected!");
18200       return -99;
18201     }
18202
18203   if (vec_len (ls_name) > 62)
18204     {
18205       errmsg ("error: locator set name too long!");
18206       return -99;
18207     }
18208
18209   if (!vam->json_output)
18210     {
18211       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18212     }
18213
18214   M (ONE_LOCATOR_DUMP, mp);
18215   mp->is_index_set = is_index_set;
18216
18217   if (is_index_set)
18218     mp->ls_index = clib_host_to_net_u32 (ls_index);
18219   else
18220     {
18221       vec_add1 (ls_name, 0);
18222       strncpy ((char *) mp->ls_name, (char *) ls_name,
18223                sizeof (mp->ls_name) - 1);
18224     }
18225
18226   /* send it... */
18227   S (mp);
18228
18229   /* Use a control ping for synchronization */
18230   MPING (CONTROL_PING, mp_ping);
18231   S (mp_ping);
18232
18233   /* Wait for a reply... */
18234   W (ret);
18235   return ret;
18236 }
18237
18238 #define api_lisp_locator_dump api_one_locator_dump
18239
18240 static int
18241 api_one_locator_set_dump (vat_main_t * vam)
18242 {
18243   vl_api_one_locator_set_dump_t *mp;
18244   vl_api_control_ping_t *mp_ping;
18245   unformat_input_t *input = vam->input;
18246   u8 filter = 0;
18247   int ret;
18248
18249   /* Parse args required to build the message */
18250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18251     {
18252       if (unformat (input, "local"))
18253         {
18254           filter = 1;
18255         }
18256       else if (unformat (input, "remote"))
18257         {
18258           filter = 2;
18259         }
18260       else
18261         {
18262           errmsg ("parse error '%U'", format_unformat_error, input);
18263           return -99;
18264         }
18265     }
18266
18267   if (!vam->json_output)
18268     {
18269       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18270     }
18271
18272   M (ONE_LOCATOR_SET_DUMP, mp);
18273
18274   mp->filter = filter;
18275
18276   /* send it... */
18277   S (mp);
18278
18279   /* Use a control ping for synchronization */
18280   MPING (CONTROL_PING, mp_ping);
18281   S (mp_ping);
18282
18283   /* Wait for a reply... */
18284   W (ret);
18285   return ret;
18286 }
18287
18288 #define api_lisp_locator_set_dump api_one_locator_set_dump
18289
18290 static int
18291 api_one_eid_table_map_dump (vat_main_t * vam)
18292 {
18293   u8 is_l2 = 0;
18294   u8 mode_set = 0;
18295   unformat_input_t *input = vam->input;
18296   vl_api_one_eid_table_map_dump_t *mp;
18297   vl_api_control_ping_t *mp_ping;
18298   int ret;
18299
18300   /* Parse args required to build the message */
18301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18302     {
18303       if (unformat (input, "l2"))
18304         {
18305           is_l2 = 1;
18306           mode_set = 1;
18307         }
18308       else if (unformat (input, "l3"))
18309         {
18310           is_l2 = 0;
18311           mode_set = 1;
18312         }
18313       else
18314         {
18315           errmsg ("parse error '%U'", format_unformat_error, input);
18316           return -99;
18317         }
18318     }
18319
18320   if (!mode_set)
18321     {
18322       errmsg ("expected one of 'l2' or 'l3' parameter!");
18323       return -99;
18324     }
18325
18326   if (!vam->json_output)
18327     {
18328       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18329     }
18330
18331   M (ONE_EID_TABLE_MAP_DUMP, mp);
18332   mp->is_l2 = is_l2;
18333
18334   /* send it... */
18335   S (mp);
18336
18337   /* Use a control ping for synchronization */
18338   MPING (CONTROL_PING, mp_ping);
18339   S (mp_ping);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18347
18348 static int
18349 api_one_eid_table_vni_dump (vat_main_t * vam)
18350 {
18351   vl_api_one_eid_table_vni_dump_t *mp;
18352   vl_api_control_ping_t *mp_ping;
18353   int ret;
18354
18355   if (!vam->json_output)
18356     {
18357       print (vam->ofp, "VNI");
18358     }
18359
18360   M (ONE_EID_TABLE_VNI_DUMP, mp);
18361
18362   /* send it... */
18363   S (mp);
18364
18365   /* Use a control ping for synchronization */
18366   MPING (CONTROL_PING, mp_ping);
18367   S (mp_ping);
18368
18369   /* Wait for a reply... */
18370   W (ret);
18371   return ret;
18372 }
18373
18374 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18375
18376 static int
18377 api_one_eid_table_dump (vat_main_t * vam)
18378 {
18379   unformat_input_t *i = vam->input;
18380   vl_api_one_eid_table_dump_t *mp;
18381   vl_api_control_ping_t *mp_ping;
18382   struct in_addr ip4;
18383   struct in6_addr ip6;
18384   u8 mac[6];
18385   u8 eid_type = ~0, eid_set = 0;
18386   u32 prefix_length = ~0, t, vni = 0;
18387   u8 filter = 0;
18388   int ret;
18389   lisp_nsh_api_t nsh;
18390
18391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18392     {
18393       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18394         {
18395           eid_set = 1;
18396           eid_type = 0;
18397           prefix_length = t;
18398         }
18399       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18400         {
18401           eid_set = 1;
18402           eid_type = 1;
18403           prefix_length = t;
18404         }
18405       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18406         {
18407           eid_set = 1;
18408           eid_type = 2;
18409         }
18410       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18411         {
18412           eid_set = 1;
18413           eid_type = 3;
18414         }
18415       else if (unformat (i, "vni %d", &t))
18416         {
18417           vni = t;
18418         }
18419       else if (unformat (i, "local"))
18420         {
18421           filter = 1;
18422         }
18423       else if (unformat (i, "remote"))
18424         {
18425           filter = 2;
18426         }
18427       else
18428         {
18429           errmsg ("parse error '%U'", format_unformat_error, i);
18430           return -99;
18431         }
18432     }
18433
18434   if (!vam->json_output)
18435     {
18436       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18437              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18438     }
18439
18440   M (ONE_EID_TABLE_DUMP, mp);
18441
18442   mp->filter = filter;
18443   if (eid_set)
18444     {
18445       mp->eid_set = 1;
18446       mp->vni = htonl (vni);
18447       mp->eid_type = eid_type;
18448       switch (eid_type)
18449         {
18450         case 0:
18451           mp->prefix_length = prefix_length;
18452           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18453           break;
18454         case 1:
18455           mp->prefix_length = prefix_length;
18456           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18457           break;
18458         case 2:
18459           clib_memcpy (mp->eid, mac, sizeof (mac));
18460           break;
18461         case 3:
18462           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18463           break;
18464         default:
18465           errmsg ("unknown EID type %d!", eid_type);
18466           return -99;
18467         }
18468     }
18469
18470   /* send it... */
18471   S (mp);
18472
18473   /* Use a control ping for synchronization */
18474   MPING (CONTROL_PING, mp_ping);
18475   S (mp_ping);
18476
18477   /* Wait for a reply... */
18478   W (ret);
18479   return ret;
18480 }
18481
18482 #define api_lisp_eid_table_dump api_one_eid_table_dump
18483
18484 static int
18485 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18486 {
18487   unformat_input_t *i = vam->input;
18488   vl_api_gpe_fwd_entries_get_t *mp;
18489   u8 vni_set = 0;
18490   u32 vni = ~0;
18491   int ret;
18492
18493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18494     {
18495       if (unformat (i, "vni %d", &vni))
18496         {
18497           vni_set = 1;
18498         }
18499       else
18500         {
18501           errmsg ("parse error '%U'", format_unformat_error, i);
18502           return -99;
18503         }
18504     }
18505
18506   if (!vni_set)
18507     {
18508       errmsg ("vni not set!");
18509       return -99;
18510     }
18511
18512   if (!vam->json_output)
18513     {
18514       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18515              "leid", "reid");
18516     }
18517
18518   M (GPE_FWD_ENTRIES_GET, mp);
18519   mp->vni = clib_host_to_net_u32 (vni);
18520
18521   /* send it... */
18522   S (mp);
18523
18524   /* Wait for a reply... */
18525   W (ret);
18526   return ret;
18527 }
18528
18529 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18530 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18531 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18532 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18533 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18534 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18535 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18536 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18537
18538 static int
18539 api_one_adjacencies_get (vat_main_t * vam)
18540 {
18541   unformat_input_t *i = vam->input;
18542   vl_api_one_adjacencies_get_t *mp;
18543   u8 vni_set = 0;
18544   u32 vni = ~0;
18545   int ret;
18546
18547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18548     {
18549       if (unformat (i, "vni %d", &vni))
18550         {
18551           vni_set = 1;
18552         }
18553       else
18554         {
18555           errmsg ("parse error '%U'", format_unformat_error, i);
18556           return -99;
18557         }
18558     }
18559
18560   if (!vni_set)
18561     {
18562       errmsg ("vni not set!");
18563       return -99;
18564     }
18565
18566   if (!vam->json_output)
18567     {
18568       print (vam->ofp, "%s %40s", "leid", "reid");
18569     }
18570
18571   M (ONE_ADJACENCIES_GET, mp);
18572   mp->vni = clib_host_to_net_u32 (vni);
18573
18574   /* send it... */
18575   S (mp);
18576
18577   /* Wait for a reply... */
18578   W (ret);
18579   return ret;
18580 }
18581
18582 #define api_lisp_adjacencies_get api_one_adjacencies_get
18583
18584 static int
18585 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18586 {
18587   unformat_input_t *i = vam->input;
18588   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18589   int ret;
18590   u8 ip_family_set = 0, is_ip4 = 1;
18591
18592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18593     {
18594       if (unformat (i, "ip4"))
18595         {
18596           ip_family_set = 1;
18597           is_ip4 = 1;
18598         }
18599       else if (unformat (i, "ip6"))
18600         {
18601           ip_family_set = 1;
18602           is_ip4 = 0;
18603         }
18604       else
18605         {
18606           errmsg ("parse error '%U'", format_unformat_error, i);
18607           return -99;
18608         }
18609     }
18610
18611   if (!ip_family_set)
18612     {
18613       errmsg ("ip family not set!");
18614       return -99;
18615     }
18616
18617   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18618   mp->is_ip4 = is_ip4;
18619
18620   /* send it... */
18621   S (mp);
18622
18623   /* Wait for a reply... */
18624   W (ret);
18625   return ret;
18626 }
18627
18628 static int
18629 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18630 {
18631   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18632   int ret;
18633
18634   if (!vam->json_output)
18635     {
18636       print (vam->ofp, "VNIs");
18637     }
18638
18639   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18640
18641   /* send it... */
18642   S (mp);
18643
18644   /* Wait for a reply... */
18645   W (ret);
18646   return ret;
18647 }
18648
18649 static int
18650 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18651 {
18652   unformat_input_t *i = vam->input;
18653   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18654   int ret = 0;
18655   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18656   struct in_addr ip4;
18657   struct in6_addr ip6;
18658   u32 table_id = 0, nh_sw_if_index = ~0;
18659
18660   memset (&ip4, 0, sizeof (ip4));
18661   memset (&ip6, 0, sizeof (ip6));
18662
18663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18664     {
18665       if (unformat (i, "del"))
18666         is_add = 0;
18667       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18668                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18669         {
18670           ip_set = 1;
18671           is_ip4 = 1;
18672         }
18673       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18674                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18675         {
18676           ip_set = 1;
18677           is_ip4 = 0;
18678         }
18679       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18680         {
18681           ip_set = 1;
18682           is_ip4 = 1;
18683           nh_sw_if_index = ~0;
18684         }
18685       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18686         {
18687           ip_set = 1;
18688           is_ip4 = 0;
18689           nh_sw_if_index = ~0;
18690         }
18691       else if (unformat (i, "table %d", &table_id))
18692         ;
18693       else
18694         {
18695           errmsg ("parse error '%U'", format_unformat_error, i);
18696           return -99;
18697         }
18698     }
18699
18700   if (!ip_set)
18701     {
18702       errmsg ("nh addr not set!");
18703       return -99;
18704     }
18705
18706   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18707   mp->is_add = is_add;
18708   mp->table_id = clib_host_to_net_u32 (table_id);
18709   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18710   mp->is_ip4 = is_ip4;
18711   if (is_ip4)
18712     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18713   else
18714     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18715
18716   /* send it... */
18717   S (mp);
18718
18719   /* Wait for a reply... */
18720   W (ret);
18721   return ret;
18722 }
18723
18724 static int
18725 api_one_map_server_dump (vat_main_t * vam)
18726 {
18727   vl_api_one_map_server_dump_t *mp;
18728   vl_api_control_ping_t *mp_ping;
18729   int ret;
18730
18731   if (!vam->json_output)
18732     {
18733       print (vam->ofp, "%=20s", "Map server");
18734     }
18735
18736   M (ONE_MAP_SERVER_DUMP, mp);
18737   /* send it... */
18738   S (mp);
18739
18740   /* Use a control ping for synchronization */
18741   MPING (CONTROL_PING, mp_ping);
18742   S (mp_ping);
18743
18744   /* Wait for a reply... */
18745   W (ret);
18746   return ret;
18747 }
18748
18749 #define api_lisp_map_server_dump api_one_map_server_dump
18750
18751 static int
18752 api_one_map_resolver_dump (vat_main_t * vam)
18753 {
18754   vl_api_one_map_resolver_dump_t *mp;
18755   vl_api_control_ping_t *mp_ping;
18756   int ret;
18757
18758   if (!vam->json_output)
18759     {
18760       print (vam->ofp, "%=20s", "Map resolver");
18761     }
18762
18763   M (ONE_MAP_RESOLVER_DUMP, mp);
18764   /* send it... */
18765   S (mp);
18766
18767   /* Use a control ping for synchronization */
18768   MPING (CONTROL_PING, mp_ping);
18769   S (mp_ping);
18770
18771   /* Wait for a reply... */
18772   W (ret);
18773   return ret;
18774 }
18775
18776 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18777
18778 static int
18779 api_one_stats_flush (vat_main_t * vam)
18780 {
18781   vl_api_one_stats_flush_t *mp;
18782   int ret = 0;
18783
18784   M (ONE_STATS_FLUSH, mp);
18785   S (mp);
18786   W (ret);
18787   return ret;
18788 }
18789
18790 static int
18791 api_one_stats_dump (vat_main_t * vam)
18792 {
18793   vl_api_one_stats_dump_t *mp;
18794   vl_api_control_ping_t *mp_ping;
18795   int ret;
18796
18797   M (ONE_STATS_DUMP, mp);
18798   /* send it... */
18799   S (mp);
18800
18801   /* Use a control ping for synchronization */
18802   MPING (CONTROL_PING, mp_ping);
18803   S (mp_ping);
18804
18805   /* Wait for a reply... */
18806   W (ret);
18807   return ret;
18808 }
18809
18810 static int
18811 api_show_one_status (vat_main_t * vam)
18812 {
18813   vl_api_show_one_status_t *mp;
18814   int ret;
18815
18816   if (!vam->json_output)
18817     {
18818       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18819     }
18820
18821   M (SHOW_ONE_STATUS, mp);
18822   /* send it... */
18823   S (mp);
18824   /* Wait for a reply... */
18825   W (ret);
18826   return ret;
18827 }
18828
18829 #define api_show_lisp_status api_show_one_status
18830
18831 static int
18832 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18833 {
18834   vl_api_gpe_fwd_entry_path_dump_t *mp;
18835   vl_api_control_ping_t *mp_ping;
18836   unformat_input_t *i = vam->input;
18837   u32 fwd_entry_index = ~0;
18838   int ret;
18839
18840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (i, "index %d", &fwd_entry_index))
18843         ;
18844       else
18845         break;
18846     }
18847
18848   if (~0 == fwd_entry_index)
18849     {
18850       errmsg ("no index specified!");
18851       return -99;
18852     }
18853
18854   if (!vam->json_output)
18855     {
18856       print (vam->ofp, "first line");
18857     }
18858
18859   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18860
18861   /* send it... */
18862   S (mp);
18863   /* Use a control ping for synchronization */
18864   MPING (CONTROL_PING, mp_ping);
18865   S (mp_ping);
18866
18867   /* Wait for a reply... */
18868   W (ret);
18869   return ret;
18870 }
18871
18872 static int
18873 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18874 {
18875   vl_api_one_get_map_request_itr_rlocs_t *mp;
18876   int ret;
18877
18878   if (!vam->json_output)
18879     {
18880       print (vam->ofp, "%=20s", "itr-rlocs:");
18881     }
18882
18883   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18884   /* send it... */
18885   S (mp);
18886   /* Wait for a reply... */
18887   W (ret);
18888   return ret;
18889 }
18890
18891 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18892
18893 static int
18894 api_af_packet_create (vat_main_t * vam)
18895 {
18896   unformat_input_t *i = vam->input;
18897   vl_api_af_packet_create_t *mp;
18898   u8 *host_if_name = 0;
18899   u8 hw_addr[6];
18900   u8 random_hw_addr = 1;
18901   int ret;
18902
18903   memset (hw_addr, 0, sizeof (hw_addr));
18904
18905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18906     {
18907       if (unformat (i, "name %s", &host_if_name))
18908         vec_add1 (host_if_name, 0);
18909       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18910         random_hw_addr = 0;
18911       else
18912         break;
18913     }
18914
18915   if (!vec_len (host_if_name))
18916     {
18917       errmsg ("host-interface name must be specified");
18918       return -99;
18919     }
18920
18921   if (vec_len (host_if_name) > 64)
18922     {
18923       errmsg ("host-interface name too long");
18924       return -99;
18925     }
18926
18927   M (AF_PACKET_CREATE, mp);
18928
18929   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18930   clib_memcpy (mp->hw_addr, hw_addr, 6);
18931   mp->use_random_hw_addr = random_hw_addr;
18932   vec_free (host_if_name);
18933
18934   S (mp);
18935
18936   /* *INDENT-OFF* */
18937   W2 (ret,
18938       ({
18939         if (ret == 0)
18940           fprintf (vam->ofp ? vam->ofp : stderr,
18941                    " new sw_if_index = %d\n", vam->sw_if_index);
18942       }));
18943   /* *INDENT-ON* */
18944   return ret;
18945 }
18946
18947 static int
18948 api_af_packet_delete (vat_main_t * vam)
18949 {
18950   unformat_input_t *i = vam->input;
18951   vl_api_af_packet_delete_t *mp;
18952   u8 *host_if_name = 0;
18953   int ret;
18954
18955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18956     {
18957       if (unformat (i, "name %s", &host_if_name))
18958         vec_add1 (host_if_name, 0);
18959       else
18960         break;
18961     }
18962
18963   if (!vec_len (host_if_name))
18964     {
18965       errmsg ("host-interface name must be specified");
18966       return -99;
18967     }
18968
18969   if (vec_len (host_if_name) > 64)
18970     {
18971       errmsg ("host-interface name too long");
18972       return -99;
18973     }
18974
18975   M (AF_PACKET_DELETE, mp);
18976
18977   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18978   vec_free (host_if_name);
18979
18980   S (mp);
18981   W (ret);
18982   return ret;
18983 }
18984
18985 static int
18986 api_policer_add_del (vat_main_t * vam)
18987 {
18988   unformat_input_t *i = vam->input;
18989   vl_api_policer_add_del_t *mp;
18990   u8 is_add = 1;
18991   u8 *name = 0;
18992   u32 cir = 0;
18993   u32 eir = 0;
18994   u64 cb = 0;
18995   u64 eb = 0;
18996   u8 rate_type = 0;
18997   u8 round_type = 0;
18998   u8 type = 0;
18999   u8 color_aware = 0;
19000   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19001   int ret;
19002
19003   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19004   conform_action.dscp = 0;
19005   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19006   exceed_action.dscp = 0;
19007   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19008   violate_action.dscp = 0;
19009
19010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19011     {
19012       if (unformat (i, "del"))
19013         is_add = 0;
19014       else if (unformat (i, "name %s", &name))
19015         vec_add1 (name, 0);
19016       else if (unformat (i, "cir %u", &cir))
19017         ;
19018       else if (unformat (i, "eir %u", &eir))
19019         ;
19020       else if (unformat (i, "cb %u", &cb))
19021         ;
19022       else if (unformat (i, "eb %u", &eb))
19023         ;
19024       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19025                          &rate_type))
19026         ;
19027       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19028                          &round_type))
19029         ;
19030       else if (unformat (i, "type %U", unformat_policer_type, &type))
19031         ;
19032       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19033                          &conform_action))
19034         ;
19035       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19036                          &exceed_action))
19037         ;
19038       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19039                          &violate_action))
19040         ;
19041       else if (unformat (i, "color-aware"))
19042         color_aware = 1;
19043       else
19044         break;
19045     }
19046
19047   if (!vec_len (name))
19048     {
19049       errmsg ("policer name must be specified");
19050       return -99;
19051     }
19052
19053   if (vec_len (name) > 64)
19054     {
19055       errmsg ("policer name too long");
19056       return -99;
19057     }
19058
19059   M (POLICER_ADD_DEL, mp);
19060
19061   clib_memcpy (mp->name, name, vec_len (name));
19062   vec_free (name);
19063   mp->is_add = is_add;
19064   mp->cir = ntohl (cir);
19065   mp->eir = ntohl (eir);
19066   mp->cb = clib_net_to_host_u64 (cb);
19067   mp->eb = clib_net_to_host_u64 (eb);
19068   mp->rate_type = rate_type;
19069   mp->round_type = round_type;
19070   mp->type = type;
19071   mp->conform_action_type = conform_action.action_type;
19072   mp->conform_dscp = conform_action.dscp;
19073   mp->exceed_action_type = exceed_action.action_type;
19074   mp->exceed_dscp = exceed_action.dscp;
19075   mp->violate_action_type = violate_action.action_type;
19076   mp->violate_dscp = violate_action.dscp;
19077   mp->color_aware = color_aware;
19078
19079   S (mp);
19080   W (ret);
19081   return ret;
19082 }
19083
19084 static int
19085 api_policer_dump (vat_main_t * vam)
19086 {
19087   unformat_input_t *i = vam->input;
19088   vl_api_policer_dump_t *mp;
19089   vl_api_control_ping_t *mp_ping;
19090   u8 *match_name = 0;
19091   u8 match_name_valid = 0;
19092   int ret;
19093
19094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (i, "name %s", &match_name))
19097         {
19098           vec_add1 (match_name, 0);
19099           match_name_valid = 1;
19100         }
19101       else
19102         break;
19103     }
19104
19105   M (POLICER_DUMP, mp);
19106   mp->match_name_valid = match_name_valid;
19107   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19108   vec_free (match_name);
19109   /* send it... */
19110   S (mp);
19111
19112   /* Use a control ping for synchronization */
19113   MPING (CONTROL_PING, mp_ping);
19114   S (mp_ping);
19115
19116   /* Wait for a reply... */
19117   W (ret);
19118   return ret;
19119 }
19120
19121 static int
19122 api_policer_classify_set_interface (vat_main_t * vam)
19123 {
19124   unformat_input_t *i = vam->input;
19125   vl_api_policer_classify_set_interface_t *mp;
19126   u32 sw_if_index;
19127   int sw_if_index_set;
19128   u32 ip4_table_index = ~0;
19129   u32 ip6_table_index = ~0;
19130   u32 l2_table_index = ~0;
19131   u8 is_add = 1;
19132   int ret;
19133
19134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19135     {
19136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19137         sw_if_index_set = 1;
19138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19139         sw_if_index_set = 1;
19140       else if (unformat (i, "del"))
19141         is_add = 0;
19142       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19143         ;
19144       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19145         ;
19146       else if (unformat (i, "l2-table %d", &l2_table_index))
19147         ;
19148       else
19149         {
19150           clib_warning ("parse error '%U'", format_unformat_error, i);
19151           return -99;
19152         }
19153     }
19154
19155   if (sw_if_index_set == 0)
19156     {
19157       errmsg ("missing interface name or sw_if_index");
19158       return -99;
19159     }
19160
19161   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19162
19163   mp->sw_if_index = ntohl (sw_if_index);
19164   mp->ip4_table_index = ntohl (ip4_table_index);
19165   mp->ip6_table_index = ntohl (ip6_table_index);
19166   mp->l2_table_index = ntohl (l2_table_index);
19167   mp->is_add = is_add;
19168
19169   S (mp);
19170   W (ret);
19171   return ret;
19172 }
19173
19174 static int
19175 api_policer_classify_dump (vat_main_t * vam)
19176 {
19177   unformat_input_t *i = vam->input;
19178   vl_api_policer_classify_dump_t *mp;
19179   vl_api_control_ping_t *mp_ping;
19180   u8 type = POLICER_CLASSIFY_N_TABLES;
19181   int ret;
19182
19183   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19184     ;
19185   else
19186     {
19187       errmsg ("classify table type must be specified");
19188       return -99;
19189     }
19190
19191   if (!vam->json_output)
19192     {
19193       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19194     }
19195
19196   M (POLICER_CLASSIFY_DUMP, mp);
19197   mp->type = type;
19198   /* send it... */
19199   S (mp);
19200
19201   /* Use a control ping for synchronization */
19202   MPING (CONTROL_PING, mp_ping);
19203   S (mp_ping);
19204
19205   /* Wait for a reply... */
19206   W (ret);
19207   return ret;
19208 }
19209
19210 static int
19211 api_netmap_create (vat_main_t * vam)
19212 {
19213   unformat_input_t *i = vam->input;
19214   vl_api_netmap_create_t *mp;
19215   u8 *if_name = 0;
19216   u8 hw_addr[6];
19217   u8 random_hw_addr = 1;
19218   u8 is_pipe = 0;
19219   u8 is_master = 0;
19220   int ret;
19221
19222   memset (hw_addr, 0, sizeof (hw_addr));
19223
19224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19225     {
19226       if (unformat (i, "name %s", &if_name))
19227         vec_add1 (if_name, 0);
19228       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19229         random_hw_addr = 0;
19230       else if (unformat (i, "pipe"))
19231         is_pipe = 1;
19232       else if (unformat (i, "master"))
19233         is_master = 1;
19234       else if (unformat (i, "slave"))
19235         is_master = 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_CREATE, mp);
19253
19254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19255   clib_memcpy (mp->hw_addr, hw_addr, 6);
19256   mp->use_random_hw_addr = random_hw_addr;
19257   mp->is_pipe = is_pipe;
19258   mp->is_master = is_master;
19259   vec_free (if_name);
19260
19261   S (mp);
19262   W (ret);
19263   return ret;
19264 }
19265
19266 static int
19267 api_netmap_delete (vat_main_t * vam)
19268 {
19269   unformat_input_t *i = vam->input;
19270   vl_api_netmap_delete_t *mp;
19271   u8 *if_name = 0;
19272   int ret;
19273
19274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19275     {
19276       if (unformat (i, "name %s", &if_name))
19277         vec_add1 (if_name, 0);
19278       else
19279         break;
19280     }
19281
19282   if (!vec_len (if_name))
19283     {
19284       errmsg ("interface name must be specified");
19285       return -99;
19286     }
19287
19288   if (vec_len (if_name) > 64)
19289     {
19290       errmsg ("interface name too long");
19291       return -99;
19292     }
19293
19294   M (NETMAP_DELETE, mp);
19295
19296   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19297   vec_free (if_name);
19298
19299   S (mp);
19300   W (ret);
19301   return ret;
19302 }
19303
19304 static void
19305 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19306 {
19307   if (fp->afi == IP46_TYPE_IP6)
19308     print (vam->ofp,
19309            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19310            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19311            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19312            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19313            format_ip6_address, fp->next_hop);
19314   else if (fp->afi == IP46_TYPE_IP4)
19315     print (vam->ofp,
19316            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19317            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19318            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19319            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19320            format_ip4_address, fp->next_hop);
19321 }
19322
19323 static void
19324 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19325                                  vl_api_fib_path2_t * fp)
19326 {
19327   struct in_addr ip4;
19328   struct in6_addr ip6;
19329
19330   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19331   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19332   vat_json_object_add_uint (node, "is_local", fp->is_local);
19333   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19334   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19335   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19336   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19337   if (fp->afi == IP46_TYPE_IP4)
19338     {
19339       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19340       vat_json_object_add_ip4 (node, "next_hop", ip4);
19341     }
19342   else if (fp->afi == IP46_TYPE_IP6)
19343     {
19344       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19345       vat_json_object_add_ip6 (node, "next_hop", ip6);
19346     }
19347 }
19348
19349 static void
19350 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19351 {
19352   vat_main_t *vam = &vat_main;
19353   int count = ntohl (mp->mt_count);
19354   vl_api_fib_path2_t *fp;
19355   i32 i;
19356
19357   print (vam->ofp, "[%d]: sw_if_index %d via:",
19358          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19359   fp = mp->mt_paths;
19360   for (i = 0; i < count; i++)
19361     {
19362       vl_api_mpls_fib_path_print (vam, fp);
19363       fp++;
19364     }
19365
19366   print (vam->ofp, "");
19367 }
19368
19369 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19370 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19371
19372 static void
19373 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19374 {
19375   vat_main_t *vam = &vat_main;
19376   vat_json_node_t *node = NULL;
19377   int count = ntohl (mp->mt_count);
19378   vl_api_fib_path2_t *fp;
19379   i32 i;
19380
19381   if (VAT_JSON_ARRAY != vam->json_tree.type)
19382     {
19383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19384       vat_json_init_array (&vam->json_tree);
19385     }
19386   node = vat_json_array_add (&vam->json_tree);
19387
19388   vat_json_init_object (node);
19389   vat_json_object_add_uint (node, "tunnel_index",
19390                             ntohl (mp->mt_tunnel_index));
19391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19392
19393   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19394
19395   fp = mp->mt_paths;
19396   for (i = 0; i < count; i++)
19397     {
19398       vl_api_mpls_fib_path_json_print (node, fp);
19399       fp++;
19400     }
19401 }
19402
19403 static int
19404 api_mpls_tunnel_dump (vat_main_t * vam)
19405 {
19406   vl_api_mpls_tunnel_dump_t *mp;
19407   vl_api_control_ping_t *mp_ping;
19408   i32 index = -1;
19409   int ret;
19410
19411   /* Parse args required to build the message */
19412   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19413     {
19414       if (!unformat (vam->input, "tunnel_index %d", &index))
19415         {
19416           index = -1;
19417           break;
19418         }
19419     }
19420
19421   print (vam->ofp, "  tunnel_index %d", index);
19422
19423   M (MPLS_TUNNEL_DUMP, mp);
19424   mp->tunnel_index = htonl (index);
19425   S (mp);
19426
19427   /* Use a control ping for synchronization */
19428   MPING (CONTROL_PING, mp_ping);
19429   S (mp_ping);
19430
19431   W (ret);
19432   return ret;
19433 }
19434
19435 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19436 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19437
19438
19439 static void
19440 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19441 {
19442   vat_main_t *vam = &vat_main;
19443   int count = ntohl (mp->count);
19444   vl_api_fib_path2_t *fp;
19445   int i;
19446
19447   print (vam->ofp,
19448          "table-id %d, label %u, ess_bit %u",
19449          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19450   fp = mp->path;
19451   for (i = 0; i < count; i++)
19452     {
19453       vl_api_mpls_fib_path_print (vam, fp);
19454       fp++;
19455     }
19456 }
19457
19458 static void vl_api_mpls_fib_details_t_handler_json
19459   (vl_api_mpls_fib_details_t * mp)
19460 {
19461   vat_main_t *vam = &vat_main;
19462   int count = ntohl (mp->count);
19463   vat_json_node_t *node = NULL;
19464   vl_api_fib_path2_t *fp;
19465   int i;
19466
19467   if (VAT_JSON_ARRAY != vam->json_tree.type)
19468     {
19469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19470       vat_json_init_array (&vam->json_tree);
19471     }
19472   node = vat_json_array_add (&vam->json_tree);
19473
19474   vat_json_init_object (node);
19475   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19476   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19477   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19478   vat_json_object_add_uint (node, "path_count", count);
19479   fp = mp->path;
19480   for (i = 0; i < count; i++)
19481     {
19482       vl_api_mpls_fib_path_json_print (node, fp);
19483       fp++;
19484     }
19485 }
19486
19487 static int
19488 api_mpls_fib_dump (vat_main_t * vam)
19489 {
19490   vl_api_mpls_fib_dump_t *mp;
19491   vl_api_control_ping_t *mp_ping;
19492   int ret;
19493
19494   M (MPLS_FIB_DUMP, mp);
19495   S (mp);
19496
19497   /* Use a control ping for synchronization */
19498   MPING (CONTROL_PING, mp_ping);
19499   S (mp_ping);
19500
19501   W (ret);
19502   return ret;
19503 }
19504
19505 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19506 #define vl_api_ip_fib_details_t_print vl_noop_handler
19507
19508 static void
19509 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19510 {
19511   vat_main_t *vam = &vat_main;
19512   int count = ntohl (mp->count);
19513   vl_api_fib_path_t *fp;
19514   int i;
19515
19516   print (vam->ofp,
19517          "table-id %d, prefix %U/%d",
19518          ntohl (mp->table_id), format_ip4_address, mp->address,
19519          mp->address_length);
19520   fp = mp->path;
19521   for (i = 0; i < count; i++)
19522     {
19523       if (fp->afi == IP46_TYPE_IP6)
19524         print (vam->ofp,
19525                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19526                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19527                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19528                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19529                format_ip6_address, fp->next_hop);
19530       else if (fp->afi == IP46_TYPE_IP4)
19531         print (vam->ofp,
19532                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19533                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19534                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19535                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19536                format_ip4_address, fp->next_hop);
19537       fp++;
19538     }
19539 }
19540
19541 static void vl_api_ip_fib_details_t_handler_json
19542   (vl_api_ip_fib_details_t * mp)
19543 {
19544   vat_main_t *vam = &vat_main;
19545   int count = ntohl (mp->count);
19546   vat_json_node_t *node = NULL;
19547   struct in_addr ip4;
19548   struct in6_addr ip6;
19549   vl_api_fib_path_t *fp;
19550   int i;
19551
19552   if (VAT_JSON_ARRAY != vam->json_tree.type)
19553     {
19554       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19555       vat_json_init_array (&vam->json_tree);
19556     }
19557   node = vat_json_array_add (&vam->json_tree);
19558
19559   vat_json_init_object (node);
19560   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19561   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19562   vat_json_object_add_ip4 (node, "prefix", ip4);
19563   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19564   vat_json_object_add_uint (node, "path_count", count);
19565   fp = mp->path;
19566   for (i = 0; i < count; i++)
19567     {
19568       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19569       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19570       vat_json_object_add_uint (node, "is_local", fp->is_local);
19571       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19572       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19573       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19574       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19575       if (fp->afi == IP46_TYPE_IP4)
19576         {
19577           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19578           vat_json_object_add_ip4 (node, "next_hop", ip4);
19579         }
19580       else if (fp->afi == IP46_TYPE_IP6)
19581         {
19582           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19583           vat_json_object_add_ip6 (node, "next_hop", ip6);
19584         }
19585     }
19586 }
19587
19588 static int
19589 api_ip_fib_dump (vat_main_t * vam)
19590 {
19591   vl_api_ip_fib_dump_t *mp;
19592   vl_api_control_ping_t *mp_ping;
19593   int ret;
19594
19595   M (IP_FIB_DUMP, mp);
19596   S (mp);
19597
19598   /* Use a control ping for synchronization */
19599   MPING (CONTROL_PING, mp_ping);
19600   S (mp_ping);
19601
19602   W (ret);
19603   return ret;
19604 }
19605
19606 static int
19607 api_ip_mfib_dump (vat_main_t * vam)
19608 {
19609   vl_api_ip_mfib_dump_t *mp;
19610   vl_api_control_ping_t *mp_ping;
19611   int ret;
19612
19613   M (IP_MFIB_DUMP, mp);
19614   S (mp);
19615
19616   /* Use a control ping for synchronization */
19617   MPING (CONTROL_PING, mp_ping);
19618   S (mp_ping);
19619
19620   W (ret);
19621   return ret;
19622 }
19623
19624 static void vl_api_ip_neighbor_details_t_handler
19625   (vl_api_ip_neighbor_details_t * mp)
19626 {
19627   vat_main_t *vam = &vat_main;
19628
19629   print (vam->ofp, "%c %U %U",
19630          (mp->is_static) ? 'S' : 'D',
19631          format_ethernet_address, &mp->mac_address,
19632          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19633          &mp->ip_address);
19634 }
19635
19636 static void vl_api_ip_neighbor_details_t_handler_json
19637   (vl_api_ip_neighbor_details_t * mp)
19638 {
19639
19640   vat_main_t *vam = &vat_main;
19641   vat_json_node_t *node;
19642   struct in_addr ip4;
19643   struct in6_addr ip6;
19644
19645   if (VAT_JSON_ARRAY != vam->json_tree.type)
19646     {
19647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19648       vat_json_init_array (&vam->json_tree);
19649     }
19650   node = vat_json_array_add (&vam->json_tree);
19651
19652   vat_json_init_object (node);
19653   vat_json_object_add_string_copy (node, "flag",
19654                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19655                                    "dynamic");
19656
19657   vat_json_object_add_string_copy (node, "link_layer",
19658                                    format (0, "%U", format_ethernet_address,
19659                                            &mp->mac_address));
19660
19661   if (mp->is_ipv6)
19662     {
19663       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19664       vat_json_object_add_ip6 (node, "ip_address", ip6);
19665     }
19666   else
19667     {
19668       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19669       vat_json_object_add_ip4 (node, "ip_address", ip4);
19670     }
19671 }
19672
19673 static int
19674 api_ip_neighbor_dump (vat_main_t * vam)
19675 {
19676   unformat_input_t *i = vam->input;
19677   vl_api_ip_neighbor_dump_t *mp;
19678   vl_api_control_ping_t *mp_ping;
19679   u8 is_ipv6 = 0;
19680   u32 sw_if_index = ~0;
19681   int ret;
19682
19683   /* Parse args required to build the message */
19684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19685     {
19686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19687         ;
19688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19689         ;
19690       else if (unformat (i, "ip6"))
19691         is_ipv6 = 1;
19692       else
19693         break;
19694     }
19695
19696   if (sw_if_index == ~0)
19697     {
19698       errmsg ("missing interface name or sw_if_index");
19699       return -99;
19700     }
19701
19702   M (IP_NEIGHBOR_DUMP, mp);
19703   mp->is_ipv6 = (u8) is_ipv6;
19704   mp->sw_if_index = ntohl (sw_if_index);
19705   S (mp);
19706
19707   /* Use a control ping for synchronization */
19708   MPING (CONTROL_PING, mp_ping);
19709   S (mp_ping);
19710
19711   W (ret);
19712   return ret;
19713 }
19714
19715 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19716 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19717
19718 static void
19719 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19720 {
19721   vat_main_t *vam = &vat_main;
19722   int count = ntohl (mp->count);
19723   vl_api_fib_path_t *fp;
19724   int i;
19725
19726   print (vam->ofp,
19727          "table-id %d, prefix %U/%d",
19728          ntohl (mp->table_id), format_ip6_address, mp->address,
19729          mp->address_length);
19730   fp = mp->path;
19731   for (i = 0; i < count; i++)
19732     {
19733       if (fp->afi == IP46_TYPE_IP6)
19734         print (vam->ofp,
19735                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19736                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19737                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19738                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19739                format_ip6_address, fp->next_hop);
19740       else if (fp->afi == IP46_TYPE_IP4)
19741         print (vam->ofp,
19742                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19743                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19744                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19745                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19746                format_ip4_address, fp->next_hop);
19747       fp++;
19748     }
19749 }
19750
19751 static void vl_api_ip6_fib_details_t_handler_json
19752   (vl_api_ip6_fib_details_t * mp)
19753 {
19754   vat_main_t *vam = &vat_main;
19755   int count = ntohl (mp->count);
19756   vat_json_node_t *node = NULL;
19757   struct in_addr ip4;
19758   struct in6_addr ip6;
19759   vl_api_fib_path_t *fp;
19760   int i;
19761
19762   if (VAT_JSON_ARRAY != vam->json_tree.type)
19763     {
19764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19765       vat_json_init_array (&vam->json_tree);
19766     }
19767   node = vat_json_array_add (&vam->json_tree);
19768
19769   vat_json_init_object (node);
19770   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19771   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19772   vat_json_object_add_ip6 (node, "prefix", ip6);
19773   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19774   vat_json_object_add_uint (node, "path_count", count);
19775   fp = mp->path;
19776   for (i = 0; i < count; i++)
19777     {
19778       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19779       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19780       vat_json_object_add_uint (node, "is_local", fp->is_local);
19781       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19782       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19783       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19784       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19785       if (fp->afi == IP46_TYPE_IP4)
19786         {
19787           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19788           vat_json_object_add_ip4 (node, "next_hop", ip4);
19789         }
19790       else if (fp->afi == IP46_TYPE_IP6)
19791         {
19792           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19793           vat_json_object_add_ip6 (node, "next_hop", ip6);
19794         }
19795     }
19796 }
19797
19798 static int
19799 api_ip6_fib_dump (vat_main_t * vam)
19800 {
19801   vl_api_ip6_fib_dump_t *mp;
19802   vl_api_control_ping_t *mp_ping;
19803   int ret;
19804
19805   M (IP6_FIB_DUMP, mp);
19806   S (mp);
19807
19808   /* Use a control ping for synchronization */
19809   MPING (CONTROL_PING, mp_ping);
19810   S (mp_ping);
19811
19812   W (ret);
19813   return ret;
19814 }
19815
19816 static int
19817 api_ip6_mfib_dump (vat_main_t * vam)
19818 {
19819   vl_api_ip6_mfib_dump_t *mp;
19820   vl_api_control_ping_t *mp_ping;
19821   int ret;
19822
19823   M (IP6_MFIB_DUMP, mp);
19824   S (mp);
19825
19826   /* Use a control ping for synchronization */
19827   MPING (CONTROL_PING, mp_ping);
19828   S (mp_ping);
19829
19830   W (ret);
19831   return ret;
19832 }
19833
19834 int
19835 api_classify_table_ids (vat_main_t * vam)
19836 {
19837   vl_api_classify_table_ids_t *mp;
19838   int ret;
19839
19840   /* Construct the API message */
19841   M (CLASSIFY_TABLE_IDS, mp);
19842   mp->context = 0;
19843
19844   S (mp);
19845   W (ret);
19846   return ret;
19847 }
19848
19849 int
19850 api_classify_table_by_interface (vat_main_t * vam)
19851 {
19852   unformat_input_t *input = vam->input;
19853   vl_api_classify_table_by_interface_t *mp;
19854
19855   u32 sw_if_index = ~0;
19856   int ret;
19857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19858     {
19859       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19860         ;
19861       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19862         ;
19863       else
19864         break;
19865     }
19866   if (sw_if_index == ~0)
19867     {
19868       errmsg ("missing interface name or sw_if_index");
19869       return -99;
19870     }
19871
19872   /* Construct the API message */
19873   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19874   mp->context = 0;
19875   mp->sw_if_index = ntohl (sw_if_index);
19876
19877   S (mp);
19878   W (ret);
19879   return ret;
19880 }
19881
19882 int
19883 api_classify_table_info (vat_main_t * vam)
19884 {
19885   unformat_input_t *input = vam->input;
19886   vl_api_classify_table_info_t *mp;
19887
19888   u32 table_id = ~0;
19889   int ret;
19890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19891     {
19892       if (unformat (input, "table_id %d", &table_id))
19893         ;
19894       else
19895         break;
19896     }
19897   if (table_id == ~0)
19898     {
19899       errmsg ("missing table id");
19900       return -99;
19901     }
19902
19903   /* Construct the API message */
19904   M (CLASSIFY_TABLE_INFO, mp);
19905   mp->context = 0;
19906   mp->table_id = ntohl (table_id);
19907
19908   S (mp);
19909   W (ret);
19910   return ret;
19911 }
19912
19913 int
19914 api_classify_session_dump (vat_main_t * vam)
19915 {
19916   unformat_input_t *input = vam->input;
19917   vl_api_classify_session_dump_t *mp;
19918   vl_api_control_ping_t *mp_ping;
19919
19920   u32 table_id = ~0;
19921   int ret;
19922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19923     {
19924       if (unformat (input, "table_id %d", &table_id))
19925         ;
19926       else
19927         break;
19928     }
19929   if (table_id == ~0)
19930     {
19931       errmsg ("missing table id");
19932       return -99;
19933     }
19934
19935   /* Construct the API message */
19936   M (CLASSIFY_SESSION_DUMP, mp);
19937   mp->context = 0;
19938   mp->table_id = ntohl (table_id);
19939   S (mp);
19940
19941   /* Use a control ping for synchronization */
19942   MPING (CONTROL_PING, mp_ping);
19943   S (mp_ping);
19944
19945   W (ret);
19946   return ret;
19947 }
19948
19949 static void
19950 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19951 {
19952   vat_main_t *vam = &vat_main;
19953
19954   print (vam->ofp, "collector_address %U, collector_port %d, "
19955          "src_address %U, vrf_id %d, path_mtu %u, "
19956          "template_interval %u, udp_checksum %d",
19957          format_ip4_address, mp->collector_address,
19958          ntohs (mp->collector_port),
19959          format_ip4_address, mp->src_address,
19960          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19961          ntohl (mp->template_interval), mp->udp_checksum);
19962
19963   vam->retval = 0;
19964   vam->result_ready = 1;
19965 }
19966
19967 static void
19968   vl_api_ipfix_exporter_details_t_handler_json
19969   (vl_api_ipfix_exporter_details_t * mp)
19970 {
19971   vat_main_t *vam = &vat_main;
19972   vat_json_node_t node;
19973   struct in_addr collector_address;
19974   struct in_addr src_address;
19975
19976   vat_json_init_object (&node);
19977   clib_memcpy (&collector_address, &mp->collector_address,
19978                sizeof (collector_address));
19979   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19980   vat_json_object_add_uint (&node, "collector_port",
19981                             ntohs (mp->collector_port));
19982   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19983   vat_json_object_add_ip4 (&node, "src_address", src_address);
19984   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19985   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19986   vat_json_object_add_uint (&node, "template_interval",
19987                             ntohl (mp->template_interval));
19988   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19989
19990   vat_json_print (vam->ofp, &node);
19991   vat_json_free (&node);
19992   vam->retval = 0;
19993   vam->result_ready = 1;
19994 }
19995
19996 int
19997 api_ipfix_exporter_dump (vat_main_t * vam)
19998 {
19999   vl_api_ipfix_exporter_dump_t *mp;
20000   int ret;
20001
20002   /* Construct the API message */
20003   M (IPFIX_EXPORTER_DUMP, mp);
20004   mp->context = 0;
20005
20006   S (mp);
20007   W (ret);
20008   return ret;
20009 }
20010
20011 static int
20012 api_ipfix_classify_stream_dump (vat_main_t * vam)
20013 {
20014   vl_api_ipfix_classify_stream_dump_t *mp;
20015   int ret;
20016
20017   /* Construct the API message */
20018   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20019   mp->context = 0;
20020
20021   S (mp);
20022   W (ret);
20023   return ret;
20024   /* NOTREACHED */
20025   return 0;
20026 }
20027
20028 static void
20029   vl_api_ipfix_classify_stream_details_t_handler
20030   (vl_api_ipfix_classify_stream_details_t * mp)
20031 {
20032   vat_main_t *vam = &vat_main;
20033   print (vam->ofp, "domain_id %d, src_port %d",
20034          ntohl (mp->domain_id), ntohs (mp->src_port));
20035   vam->retval = 0;
20036   vam->result_ready = 1;
20037 }
20038
20039 static void
20040   vl_api_ipfix_classify_stream_details_t_handler_json
20041   (vl_api_ipfix_classify_stream_details_t * mp)
20042 {
20043   vat_main_t *vam = &vat_main;
20044   vat_json_node_t node;
20045
20046   vat_json_init_object (&node);
20047   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20048   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20049
20050   vat_json_print (vam->ofp, &node);
20051   vat_json_free (&node);
20052   vam->retval = 0;
20053   vam->result_ready = 1;
20054 }
20055
20056 static int
20057 api_ipfix_classify_table_dump (vat_main_t * vam)
20058 {
20059   vl_api_ipfix_classify_table_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   int ret;
20062
20063   if (!vam->json_output)
20064     {
20065       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20066              "transport_protocol");
20067     }
20068
20069   /* Construct the API message */
20070   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20071
20072   /* send it... */
20073   S (mp);
20074
20075   /* Use a control ping for synchronization */
20076   MPING (CONTROL_PING, mp_ping);
20077   S (mp_ping);
20078
20079   W (ret);
20080   return ret;
20081 }
20082
20083 static void
20084   vl_api_ipfix_classify_table_details_t_handler
20085   (vl_api_ipfix_classify_table_details_t * mp)
20086 {
20087   vat_main_t *vam = &vat_main;
20088   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20089          mp->transport_protocol);
20090 }
20091
20092 static void
20093   vl_api_ipfix_classify_table_details_t_handler_json
20094   (vl_api_ipfix_classify_table_details_t * mp)
20095 {
20096   vat_json_node_t *node = NULL;
20097   vat_main_t *vam = &vat_main;
20098
20099   if (VAT_JSON_ARRAY != vam->json_tree.type)
20100     {
20101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20102       vat_json_init_array (&vam->json_tree);
20103     }
20104
20105   node = vat_json_array_add (&vam->json_tree);
20106   vat_json_init_object (node);
20107
20108   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20109   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20110   vat_json_object_add_uint (node, "transport_protocol",
20111                             mp->transport_protocol);
20112 }
20113
20114 static int
20115 api_sw_interface_span_enable_disable (vat_main_t * vam)
20116 {
20117   unformat_input_t *i = vam->input;
20118   vl_api_sw_interface_span_enable_disable_t *mp;
20119   u32 src_sw_if_index = ~0;
20120   u32 dst_sw_if_index = ~0;
20121   u8 state = 3;
20122   int ret;
20123   u8 is_l2 = 0;
20124
20125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20126     {
20127       if (unformat
20128           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20129         ;
20130       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20131         ;
20132       else
20133         if (unformat
20134             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20135         ;
20136       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20137         ;
20138       else if (unformat (i, "disable"))
20139         state = 0;
20140       else if (unformat (i, "rx"))
20141         state = 1;
20142       else if (unformat (i, "tx"))
20143         state = 2;
20144       else if (unformat (i, "both"))
20145         state = 3;
20146       else if (unformat (i, "l2"))
20147         is_l2 = 1;
20148       else
20149         break;
20150     }
20151
20152   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20153
20154   mp->sw_if_index_from = htonl (src_sw_if_index);
20155   mp->sw_if_index_to = htonl (dst_sw_if_index);
20156   mp->state = state;
20157   mp->is_l2 = is_l2;
20158
20159   S (mp);
20160   W (ret);
20161   return ret;
20162 }
20163
20164 static void
20165 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20166                                             * mp)
20167 {
20168   vat_main_t *vam = &vat_main;
20169   u8 *sw_if_from_name = 0;
20170   u8 *sw_if_to_name = 0;
20171   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20172   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20173   char *states[] = { "none", "rx", "tx", "both" };
20174   hash_pair_t *p;
20175
20176   /* *INDENT-OFF* */
20177   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20178   ({
20179     if ((u32) p->value[0] == sw_if_index_from)
20180       {
20181         sw_if_from_name = (u8 *)(p->key);
20182         if (sw_if_to_name)
20183           break;
20184       }
20185     if ((u32) p->value[0] == sw_if_index_to)
20186       {
20187         sw_if_to_name = (u8 *)(p->key);
20188         if (sw_if_from_name)
20189           break;
20190       }
20191   }));
20192   /* *INDENT-ON* */
20193   print (vam->ofp, "%20s => %20s (%s)",
20194          sw_if_from_name, sw_if_to_name, states[mp->state]);
20195 }
20196
20197 static void
20198   vl_api_sw_interface_span_details_t_handler_json
20199   (vl_api_sw_interface_span_details_t * mp)
20200 {
20201   vat_main_t *vam = &vat_main;
20202   vat_json_node_t *node = NULL;
20203   u8 *sw_if_from_name = 0;
20204   u8 *sw_if_to_name = 0;
20205   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20206   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20207   hash_pair_t *p;
20208
20209   /* *INDENT-OFF* */
20210   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20211   ({
20212     if ((u32) p->value[0] == sw_if_index_from)
20213       {
20214         sw_if_from_name = (u8 *)(p->key);
20215         if (sw_if_to_name)
20216           break;
20217       }
20218     if ((u32) p->value[0] == sw_if_index_to)
20219       {
20220         sw_if_to_name = (u8 *)(p->key);
20221         if (sw_if_from_name)
20222           break;
20223       }
20224   }));
20225   /* *INDENT-ON* */
20226
20227   if (VAT_JSON_ARRAY != vam->json_tree.type)
20228     {
20229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20230       vat_json_init_array (&vam->json_tree);
20231     }
20232   node = vat_json_array_add (&vam->json_tree);
20233
20234   vat_json_init_object (node);
20235   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20236   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20237   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20238   if (0 != sw_if_to_name)
20239     {
20240       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20241     }
20242   vat_json_object_add_uint (node, "state", mp->state);
20243 }
20244
20245 static int
20246 api_sw_interface_span_dump (vat_main_t * vam)
20247 {
20248   unformat_input_t *input = vam->input;
20249   vl_api_sw_interface_span_dump_t *mp;
20250   vl_api_control_ping_t *mp_ping;
20251   u8 is_l2 = 0;
20252   int ret;
20253
20254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20255     {
20256       if (unformat (input, "l2"))
20257         is_l2 = 1;
20258       else
20259         break;
20260     }
20261
20262   M (SW_INTERFACE_SPAN_DUMP, mp);
20263   mp->is_l2 = is_l2;
20264   S (mp);
20265
20266   /* Use a control ping for synchronization */
20267   MPING (CONTROL_PING, mp_ping);
20268   S (mp_ping);
20269
20270   W (ret);
20271   return ret;
20272 }
20273
20274 int
20275 api_pg_create_interface (vat_main_t * vam)
20276 {
20277   unformat_input_t *input = vam->input;
20278   vl_api_pg_create_interface_t *mp;
20279
20280   u32 if_id = ~0;
20281   int ret;
20282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20283     {
20284       if (unformat (input, "if_id %d", &if_id))
20285         ;
20286       else
20287         break;
20288     }
20289   if (if_id == ~0)
20290     {
20291       errmsg ("missing pg interface index");
20292       return -99;
20293     }
20294
20295   /* Construct the API message */
20296   M (PG_CREATE_INTERFACE, mp);
20297   mp->context = 0;
20298   mp->interface_id = ntohl (if_id);
20299
20300   S (mp);
20301   W (ret);
20302   return ret;
20303 }
20304
20305 int
20306 api_pg_capture (vat_main_t * vam)
20307 {
20308   unformat_input_t *input = vam->input;
20309   vl_api_pg_capture_t *mp;
20310
20311   u32 if_id = ~0;
20312   u8 enable = 1;
20313   u32 count = 1;
20314   u8 pcap_file_set = 0;
20315   u8 *pcap_file = 0;
20316   int ret;
20317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20318     {
20319       if (unformat (input, "if_id %d", &if_id))
20320         ;
20321       else if (unformat (input, "pcap %s", &pcap_file))
20322         pcap_file_set = 1;
20323       else if (unformat (input, "count %d", &count))
20324         ;
20325       else if (unformat (input, "disable"))
20326         enable = 0;
20327       else
20328         break;
20329     }
20330   if (if_id == ~0)
20331     {
20332       errmsg ("missing pg interface index");
20333       return -99;
20334     }
20335   if (pcap_file_set > 0)
20336     {
20337       if (vec_len (pcap_file) > 255)
20338         {
20339           errmsg ("pcap file name is too long");
20340           return -99;
20341         }
20342     }
20343
20344   u32 name_len = vec_len (pcap_file);
20345   /* Construct the API message */
20346   M (PG_CAPTURE, mp);
20347   mp->context = 0;
20348   mp->interface_id = ntohl (if_id);
20349   mp->is_enabled = enable;
20350   mp->count = ntohl (count);
20351   mp->pcap_name_length = ntohl (name_len);
20352   if (pcap_file_set != 0)
20353     {
20354       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20355     }
20356   vec_free (pcap_file);
20357
20358   S (mp);
20359   W (ret);
20360   return ret;
20361 }
20362
20363 int
20364 api_pg_enable_disable (vat_main_t * vam)
20365 {
20366   unformat_input_t *input = vam->input;
20367   vl_api_pg_enable_disable_t *mp;
20368
20369   u8 enable = 1;
20370   u8 stream_name_set = 0;
20371   u8 *stream_name = 0;
20372   int ret;
20373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20374     {
20375       if (unformat (input, "stream %s", &stream_name))
20376         stream_name_set = 1;
20377       else if (unformat (input, "disable"))
20378         enable = 0;
20379       else
20380         break;
20381     }
20382
20383   if (stream_name_set > 0)
20384     {
20385       if (vec_len (stream_name) > 255)
20386         {
20387           errmsg ("stream name too long");
20388           return -99;
20389         }
20390     }
20391
20392   u32 name_len = vec_len (stream_name);
20393   /* Construct the API message */
20394   M (PG_ENABLE_DISABLE, mp);
20395   mp->context = 0;
20396   mp->is_enabled = enable;
20397   if (stream_name_set != 0)
20398     {
20399       mp->stream_name_length = ntohl (name_len);
20400       clib_memcpy (mp->stream_name, stream_name, name_len);
20401     }
20402   vec_free (stream_name);
20403
20404   S (mp);
20405   W (ret);
20406   return ret;
20407 }
20408
20409 int
20410 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20411 {
20412   unformat_input_t *input = vam->input;
20413   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20414
20415   u16 *low_ports = 0;
20416   u16 *high_ports = 0;
20417   u16 this_low;
20418   u16 this_hi;
20419   ip4_address_t ip4_addr;
20420   ip6_address_t ip6_addr;
20421   u32 length;
20422   u32 tmp, tmp2;
20423   u8 prefix_set = 0;
20424   u32 vrf_id = ~0;
20425   u8 is_add = 1;
20426   u8 is_ipv6 = 0;
20427   int ret;
20428
20429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20430     {
20431       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20432         {
20433           prefix_set = 1;
20434         }
20435       else
20436         if (unformat
20437             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20438         {
20439           prefix_set = 1;
20440           is_ipv6 = 1;
20441         }
20442       else if (unformat (input, "vrf %d", &vrf_id))
20443         ;
20444       else if (unformat (input, "del"))
20445         is_add = 0;
20446       else if (unformat (input, "port %d", &tmp))
20447         {
20448           if (tmp == 0 || tmp > 65535)
20449             {
20450               errmsg ("port %d out of range", tmp);
20451               return -99;
20452             }
20453           this_low = tmp;
20454           this_hi = this_low + 1;
20455           vec_add1 (low_ports, this_low);
20456           vec_add1 (high_ports, this_hi);
20457         }
20458       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20459         {
20460           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20461             {
20462               errmsg ("incorrect range parameters");
20463               return -99;
20464             }
20465           this_low = tmp;
20466           /* Note: in debug CLI +1 is added to high before
20467              passing to real fn that does "the work"
20468              (ip_source_and_port_range_check_add_del).
20469              This fn is a wrapper around the binary API fn a
20470              control plane will call, which expects this increment
20471              to have occurred. Hence letting the binary API control
20472              plane fn do the increment for consistency between VAT
20473              and other control planes.
20474            */
20475           this_hi = tmp2;
20476           vec_add1 (low_ports, this_low);
20477           vec_add1 (high_ports, this_hi);
20478         }
20479       else
20480         break;
20481     }
20482
20483   if (prefix_set == 0)
20484     {
20485       errmsg ("<address>/<mask> not specified");
20486       return -99;
20487     }
20488
20489   if (vrf_id == ~0)
20490     {
20491       errmsg ("VRF ID required, not specified");
20492       return -99;
20493     }
20494
20495   if (vrf_id == 0)
20496     {
20497       errmsg
20498         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20499       return -99;
20500     }
20501
20502   if (vec_len (low_ports) == 0)
20503     {
20504       errmsg ("At least one port or port range required");
20505       return -99;
20506     }
20507
20508   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20509
20510   mp->is_add = is_add;
20511
20512   if (is_ipv6)
20513     {
20514       mp->is_ipv6 = 1;
20515       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20516     }
20517   else
20518     {
20519       mp->is_ipv6 = 0;
20520       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20521     }
20522
20523   mp->mask_length = length;
20524   mp->number_of_ranges = vec_len (low_ports);
20525
20526   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20527   vec_free (low_ports);
20528
20529   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20530   vec_free (high_ports);
20531
20532   mp->vrf_id = ntohl (vrf_id);
20533
20534   S (mp);
20535   W (ret);
20536   return ret;
20537 }
20538
20539 int
20540 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20541 {
20542   unformat_input_t *input = vam->input;
20543   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20544   u32 sw_if_index = ~0;
20545   int vrf_set = 0;
20546   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20547   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20548   u8 is_add = 1;
20549   int ret;
20550
20551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20552     {
20553       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20554         ;
20555       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20556         ;
20557       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20558         vrf_set = 1;
20559       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20560         vrf_set = 1;
20561       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20562         vrf_set = 1;
20563       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20564         vrf_set = 1;
20565       else if (unformat (input, "del"))
20566         is_add = 0;
20567       else
20568         break;
20569     }
20570
20571   if (sw_if_index == ~0)
20572     {
20573       errmsg ("Interface required but not specified");
20574       return -99;
20575     }
20576
20577   if (vrf_set == 0)
20578     {
20579       errmsg ("VRF ID required but not specified");
20580       return -99;
20581     }
20582
20583   if (tcp_out_vrf_id == 0
20584       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20585     {
20586       errmsg
20587         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20588       return -99;
20589     }
20590
20591   /* Construct the API message */
20592   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20593
20594   mp->sw_if_index = ntohl (sw_if_index);
20595   mp->is_add = is_add;
20596   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20597   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20598   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20599   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20600
20601   /* send it... */
20602   S (mp);
20603
20604   /* Wait for a reply... */
20605   W (ret);
20606   return ret;
20607 }
20608
20609 static int
20610 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20611 {
20612   unformat_input_t *i = vam->input;
20613   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20614   u32 local_sa_id = 0;
20615   u32 remote_sa_id = 0;
20616   ip4_address_t src_address;
20617   ip4_address_t dst_address;
20618   u8 is_add = 1;
20619   int ret;
20620
20621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20622     {
20623       if (unformat (i, "local_sa %d", &local_sa_id))
20624         ;
20625       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20626         ;
20627       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20628         ;
20629       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20630         ;
20631       else if (unformat (i, "del"))
20632         is_add = 0;
20633       else
20634         {
20635           clib_warning ("parse error '%U'", format_unformat_error, i);
20636           return -99;
20637         }
20638     }
20639
20640   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20641
20642   mp->local_sa_id = ntohl (local_sa_id);
20643   mp->remote_sa_id = ntohl (remote_sa_id);
20644   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20645   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20646   mp->is_add = is_add;
20647
20648   S (mp);
20649   W (ret);
20650   return ret;
20651 }
20652
20653 static int
20654 api_punt (vat_main_t * vam)
20655 {
20656   unformat_input_t *i = vam->input;
20657   vl_api_punt_t *mp;
20658   u32 ipv = ~0;
20659   u32 protocol = ~0;
20660   u32 port = ~0;
20661   int is_add = 1;
20662   int ret;
20663
20664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20665     {
20666       if (unformat (i, "ip %d", &ipv))
20667         ;
20668       else if (unformat (i, "protocol %d", &protocol))
20669         ;
20670       else if (unformat (i, "port %d", &port))
20671         ;
20672       else if (unformat (i, "del"))
20673         is_add = 0;
20674       else
20675         {
20676           clib_warning ("parse error '%U'", format_unformat_error, i);
20677           return -99;
20678         }
20679     }
20680
20681   M (PUNT, mp);
20682
20683   mp->is_add = (u8) is_add;
20684   mp->ipv = (u8) ipv;
20685   mp->l4_protocol = (u8) protocol;
20686   mp->l4_port = htons ((u16) port);
20687
20688   S (mp);
20689   W (ret);
20690   return ret;
20691 }
20692
20693 static void vl_api_ipsec_gre_tunnel_details_t_handler
20694   (vl_api_ipsec_gre_tunnel_details_t * mp)
20695 {
20696   vat_main_t *vam = &vat_main;
20697
20698   print (vam->ofp, "%11d%15U%15U%14d%14d",
20699          ntohl (mp->sw_if_index),
20700          format_ip4_address, &mp->src_address,
20701          format_ip4_address, &mp->dst_address,
20702          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20703 }
20704
20705 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20706   (vl_api_ipsec_gre_tunnel_details_t * mp)
20707 {
20708   vat_main_t *vam = &vat_main;
20709   vat_json_node_t *node = NULL;
20710   struct in_addr ip4;
20711
20712   if (VAT_JSON_ARRAY != vam->json_tree.type)
20713     {
20714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20715       vat_json_init_array (&vam->json_tree);
20716     }
20717   node = vat_json_array_add (&vam->json_tree);
20718
20719   vat_json_init_object (node);
20720   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20721   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20722   vat_json_object_add_ip4 (node, "src_address", ip4);
20723   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20724   vat_json_object_add_ip4 (node, "dst_address", ip4);
20725   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20726   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20727 }
20728
20729 static int
20730 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20731 {
20732   unformat_input_t *i = vam->input;
20733   vl_api_ipsec_gre_tunnel_dump_t *mp;
20734   vl_api_control_ping_t *mp_ping;
20735   u32 sw_if_index;
20736   u8 sw_if_index_set = 0;
20737   int ret;
20738
20739   /* Parse args required to build the message */
20740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20741     {
20742       if (unformat (i, "sw_if_index %d", &sw_if_index))
20743         sw_if_index_set = 1;
20744       else
20745         break;
20746     }
20747
20748   if (sw_if_index_set == 0)
20749     {
20750       sw_if_index = ~0;
20751     }
20752
20753   if (!vam->json_output)
20754     {
20755       print (vam->ofp, "%11s%15s%15s%14s%14s",
20756              "sw_if_index", "src_address", "dst_address",
20757              "local_sa_id", "remote_sa_id");
20758     }
20759
20760   /* Get list of gre-tunnel interfaces */
20761   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20762
20763   mp->sw_if_index = htonl (sw_if_index);
20764
20765   S (mp);
20766
20767   /* Use a control ping for synchronization */
20768   MPING (CONTROL_PING, mp_ping);
20769   S (mp_ping);
20770
20771   W (ret);
20772   return ret;
20773 }
20774
20775 static int
20776 api_delete_subif (vat_main_t * vam)
20777 {
20778   unformat_input_t *i = vam->input;
20779   vl_api_delete_subif_t *mp;
20780   u32 sw_if_index = ~0;
20781   int ret;
20782
20783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20784     {
20785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20786         ;
20787       if (unformat (i, "sw_if_index %d", &sw_if_index))
20788         ;
20789       else
20790         break;
20791     }
20792
20793   if (sw_if_index == ~0)
20794     {
20795       errmsg ("missing sw_if_index");
20796       return -99;
20797     }
20798
20799   /* Construct the API message */
20800   M (DELETE_SUBIF, mp);
20801   mp->sw_if_index = ntohl (sw_if_index);
20802
20803   S (mp);
20804   W (ret);
20805   return ret;
20806 }
20807
20808 #define foreach_pbb_vtr_op      \
20809 _("disable",  L2_VTR_DISABLED)  \
20810 _("pop",  L2_VTR_POP_2)         \
20811 _("push",  L2_VTR_PUSH_2)
20812
20813 static int
20814 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20815 {
20816   unformat_input_t *i = vam->input;
20817   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20818   u32 sw_if_index = ~0, vtr_op = ~0;
20819   u16 outer_tag = ~0;
20820   u8 dmac[6], smac[6];
20821   u8 dmac_set = 0, smac_set = 0;
20822   u16 vlanid = 0;
20823   u32 sid = ~0;
20824   u32 tmp;
20825   int ret;
20826
20827   /* Shut up coverity */
20828   memset (dmac, 0, sizeof (dmac));
20829   memset (smac, 0, sizeof (smac));
20830
20831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20832     {
20833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20834         ;
20835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20836         ;
20837       else if (unformat (i, "vtr_op %d", &vtr_op))
20838         ;
20839 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20840       foreach_pbb_vtr_op
20841 #undef _
20842         else if (unformat (i, "translate_pbb_stag"))
20843         {
20844           if (unformat (i, "%d", &tmp))
20845             {
20846               vtr_op = L2_VTR_TRANSLATE_2_1;
20847               outer_tag = tmp;
20848             }
20849           else
20850             {
20851               errmsg
20852                 ("translate_pbb_stag operation requires outer tag definition");
20853               return -99;
20854             }
20855         }
20856       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20857         dmac_set++;
20858       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20859         smac_set++;
20860       else if (unformat (i, "sid %d", &sid))
20861         ;
20862       else if (unformat (i, "vlanid %d", &tmp))
20863         vlanid = tmp;
20864       else
20865         {
20866           clib_warning ("parse error '%U'", format_unformat_error, i);
20867           return -99;
20868         }
20869     }
20870
20871   if ((sw_if_index == ~0) || (vtr_op == ~0))
20872     {
20873       errmsg ("missing sw_if_index or vtr operation");
20874       return -99;
20875     }
20876   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20877       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20878     {
20879       errmsg
20880         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20881       return -99;
20882     }
20883
20884   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20885   mp->sw_if_index = ntohl (sw_if_index);
20886   mp->vtr_op = ntohl (vtr_op);
20887   mp->outer_tag = ntohs (outer_tag);
20888   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20889   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20890   mp->b_vlanid = ntohs (vlanid);
20891   mp->i_sid = ntohl (sid);
20892
20893   S (mp);
20894   W (ret);
20895   return ret;
20896 }
20897
20898 static int
20899 api_flow_classify_set_interface (vat_main_t * vam)
20900 {
20901   unformat_input_t *i = vam->input;
20902   vl_api_flow_classify_set_interface_t *mp;
20903   u32 sw_if_index;
20904   int sw_if_index_set;
20905   u32 ip4_table_index = ~0;
20906   u32 ip6_table_index = ~0;
20907   u8 is_add = 1;
20908   int ret;
20909
20910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20911     {
20912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20913         sw_if_index_set = 1;
20914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20915         sw_if_index_set = 1;
20916       else if (unformat (i, "del"))
20917         is_add = 0;
20918       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20919         ;
20920       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20921         ;
20922       else
20923         {
20924           clib_warning ("parse error '%U'", format_unformat_error, i);
20925           return -99;
20926         }
20927     }
20928
20929   if (sw_if_index_set == 0)
20930     {
20931       errmsg ("missing interface name or sw_if_index");
20932       return -99;
20933     }
20934
20935   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20936
20937   mp->sw_if_index = ntohl (sw_if_index);
20938   mp->ip4_table_index = ntohl (ip4_table_index);
20939   mp->ip6_table_index = ntohl (ip6_table_index);
20940   mp->is_add = is_add;
20941
20942   S (mp);
20943   W (ret);
20944   return ret;
20945 }
20946
20947 static int
20948 api_flow_classify_dump (vat_main_t * vam)
20949 {
20950   unformat_input_t *i = vam->input;
20951   vl_api_flow_classify_dump_t *mp;
20952   vl_api_control_ping_t *mp_ping;
20953   u8 type = FLOW_CLASSIFY_N_TABLES;
20954   int ret;
20955
20956   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20957     ;
20958   else
20959     {
20960       errmsg ("classify table type must be specified");
20961       return -99;
20962     }
20963
20964   if (!vam->json_output)
20965     {
20966       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20967     }
20968
20969   M (FLOW_CLASSIFY_DUMP, mp);
20970   mp->type = type;
20971   /* send it... */
20972   S (mp);
20973
20974   /* Use a control ping for synchronization */
20975   MPING (CONTROL_PING, mp_ping);
20976   S (mp_ping);
20977
20978   /* Wait for a reply... */
20979   W (ret);
20980   return ret;
20981 }
20982
20983 static int
20984 api_feature_enable_disable (vat_main_t * vam)
20985 {
20986   unformat_input_t *i = vam->input;
20987   vl_api_feature_enable_disable_t *mp;
20988   u8 *arc_name = 0;
20989   u8 *feature_name = 0;
20990   u32 sw_if_index = ~0;
20991   u8 enable = 1;
20992   int ret;
20993
20994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (i, "arc_name %s", &arc_name))
20997         ;
20998       else if (unformat (i, "feature_name %s", &feature_name))
20999         ;
21000       else
21001         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21002         ;
21003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21004         ;
21005       else if (unformat (i, "disable"))
21006         enable = 0;
21007       else
21008         break;
21009     }
21010
21011   if (arc_name == 0)
21012     {
21013       errmsg ("missing arc name");
21014       return -99;
21015     }
21016   if (vec_len (arc_name) > 63)
21017     {
21018       errmsg ("arc name too long");
21019     }
21020
21021   if (feature_name == 0)
21022     {
21023       errmsg ("missing feature name");
21024       return -99;
21025     }
21026   if (vec_len (feature_name) > 63)
21027     {
21028       errmsg ("feature name too long");
21029     }
21030
21031   if (sw_if_index == ~0)
21032     {
21033       errmsg ("missing interface name or sw_if_index");
21034       return -99;
21035     }
21036
21037   /* Construct the API message */
21038   M (FEATURE_ENABLE_DISABLE, mp);
21039   mp->sw_if_index = ntohl (sw_if_index);
21040   mp->enable = enable;
21041   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21042   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21043   vec_free (arc_name);
21044   vec_free (feature_name);
21045
21046   S (mp);
21047   W (ret);
21048   return ret;
21049 }
21050
21051 static int
21052 api_sw_interface_tag_add_del (vat_main_t * vam)
21053 {
21054   unformat_input_t *i = vam->input;
21055   vl_api_sw_interface_tag_add_del_t *mp;
21056   u32 sw_if_index = ~0;
21057   u8 *tag = 0;
21058   u8 enable = 1;
21059   int ret;
21060
21061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21062     {
21063       if (unformat (i, "tag %s", &tag))
21064         ;
21065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21066         ;
21067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21068         ;
21069       else if (unformat (i, "del"))
21070         enable = 0;
21071       else
21072         break;
21073     }
21074
21075   if (sw_if_index == ~0)
21076     {
21077       errmsg ("missing interface name or sw_if_index");
21078       return -99;
21079     }
21080
21081   if (enable && (tag == 0))
21082     {
21083       errmsg ("no tag specified");
21084       return -99;
21085     }
21086
21087   /* Construct the API message */
21088   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21089   mp->sw_if_index = ntohl (sw_if_index);
21090   mp->is_add = enable;
21091   if (enable)
21092     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21093   vec_free (tag);
21094
21095   S (mp);
21096   W (ret);
21097   return ret;
21098 }
21099
21100 static void vl_api_l2_xconnect_details_t_handler
21101   (vl_api_l2_xconnect_details_t * mp)
21102 {
21103   vat_main_t *vam = &vat_main;
21104
21105   print (vam->ofp, "%15d%15d",
21106          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21107 }
21108
21109 static void vl_api_l2_xconnect_details_t_handler_json
21110   (vl_api_l2_xconnect_details_t * mp)
21111 {
21112   vat_main_t *vam = &vat_main;
21113   vat_json_node_t *node = NULL;
21114
21115   if (VAT_JSON_ARRAY != vam->json_tree.type)
21116     {
21117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21118       vat_json_init_array (&vam->json_tree);
21119     }
21120   node = vat_json_array_add (&vam->json_tree);
21121
21122   vat_json_init_object (node);
21123   vat_json_object_add_uint (node, "rx_sw_if_index",
21124                             ntohl (mp->rx_sw_if_index));
21125   vat_json_object_add_uint (node, "tx_sw_if_index",
21126                             ntohl (mp->tx_sw_if_index));
21127 }
21128
21129 static int
21130 api_l2_xconnect_dump (vat_main_t * vam)
21131 {
21132   vl_api_l2_xconnect_dump_t *mp;
21133   vl_api_control_ping_t *mp_ping;
21134   int ret;
21135
21136   if (!vam->json_output)
21137     {
21138       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21139     }
21140
21141   M (L2_XCONNECT_DUMP, mp);
21142
21143   S (mp);
21144
21145   /* Use a control ping for synchronization */
21146   MPING (CONTROL_PING, mp_ping);
21147   S (mp_ping);
21148
21149   W (ret);
21150   return ret;
21151 }
21152
21153 static int
21154 api_sw_interface_set_mtu (vat_main_t * vam)
21155 {
21156   unformat_input_t *i = vam->input;
21157   vl_api_sw_interface_set_mtu_t *mp;
21158   u32 sw_if_index = ~0;
21159   u32 mtu = 0;
21160   int ret;
21161
21162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21163     {
21164       if (unformat (i, "mtu %d", &mtu))
21165         ;
21166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21167         ;
21168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21169         ;
21170       else
21171         break;
21172     }
21173
21174   if (sw_if_index == ~0)
21175     {
21176       errmsg ("missing interface name or sw_if_index");
21177       return -99;
21178     }
21179
21180   if (mtu == 0)
21181     {
21182       errmsg ("no mtu specified");
21183       return -99;
21184     }
21185
21186   /* Construct the API message */
21187   M (SW_INTERFACE_SET_MTU, mp);
21188   mp->sw_if_index = ntohl (sw_if_index);
21189   mp->mtu = ntohs ((u16) mtu);
21190
21191   S (mp);
21192   W (ret);
21193   return ret;
21194 }
21195
21196 static int
21197 api_p2p_ethernet_add (vat_main_t * vam)
21198 {
21199   unformat_input_t *i = vam->input;
21200   vl_api_p2p_ethernet_add_t *mp;
21201   u32 parent_if_index = ~0;
21202   u32 sub_id = ~0;
21203   u8 remote_mac[6];
21204   u8 mac_set = 0;
21205   int ret;
21206
21207   memset (remote_mac, 0, sizeof (remote_mac));
21208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21209     {
21210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21211         ;
21212       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21213         ;
21214       else
21215         if (unformat
21216             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21217         mac_set++;
21218       else if (unformat (i, "sub_id %d", &sub_id))
21219         ;
21220       else
21221         {
21222           clib_warning ("parse error '%U'", format_unformat_error, i);
21223           return -99;
21224         }
21225     }
21226
21227   if (parent_if_index == ~0)
21228     {
21229       errmsg ("missing interface name or sw_if_index");
21230       return -99;
21231     }
21232   if (mac_set == 0)
21233     {
21234       errmsg ("missing remote mac address");
21235       return -99;
21236     }
21237   if (sub_id == ~0)
21238     {
21239       errmsg ("missing sub-interface id");
21240       return -99;
21241     }
21242
21243   M (P2P_ETHERNET_ADD, mp);
21244   mp->parent_if_index = ntohl (parent_if_index);
21245   mp->subif_id = ntohl (sub_id);
21246   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21247
21248   S (mp);
21249   W (ret);
21250   return ret;
21251 }
21252
21253 static int
21254 api_p2p_ethernet_del (vat_main_t * vam)
21255 {
21256   unformat_input_t *i = vam->input;
21257   vl_api_p2p_ethernet_del_t *mp;
21258   u32 parent_if_index = ~0;
21259   u8 remote_mac[6];
21260   u8 mac_set = 0;
21261   int ret;
21262
21263   memset (remote_mac, 0, sizeof (remote_mac));
21264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21265     {
21266       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21267         ;
21268       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21269         ;
21270       else
21271         if (unformat
21272             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21273         mac_set++;
21274       else
21275         {
21276           clib_warning ("parse error '%U'", format_unformat_error, i);
21277           return -99;
21278         }
21279     }
21280
21281   if (parent_if_index == ~0)
21282     {
21283       errmsg ("missing interface name or sw_if_index");
21284       return -99;
21285     }
21286   if (mac_set == 0)
21287     {
21288       errmsg ("missing remote mac address");
21289       return -99;
21290     }
21291
21292   M (P2P_ETHERNET_DEL, mp);
21293   mp->parent_if_index = ntohl (parent_if_index);
21294   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21295
21296   S (mp);
21297   W (ret);
21298   return ret;
21299 }
21300
21301 static int
21302 api_lldp_config (vat_main_t * vam)
21303 {
21304   unformat_input_t *i = vam->input;
21305   vl_api_lldp_config_t *mp;
21306   int tx_hold = 0;
21307   int tx_interval = 0;
21308   u8 *sys_name = NULL;
21309   int ret;
21310
21311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21312     {
21313       if (unformat (i, "system-name %s", &sys_name))
21314         ;
21315       else if (unformat (i, "tx-hold %d", &tx_hold))
21316         ;
21317       else if (unformat (i, "tx-interval %d", &tx_interval))
21318         ;
21319       else
21320         {
21321           clib_warning ("parse error '%U'", format_unformat_error, i);
21322           return -99;
21323         }
21324     }
21325
21326   vec_add1 (sys_name, 0);
21327
21328   M (LLDP_CONFIG, mp);
21329   mp->tx_hold = htonl (tx_hold);
21330   mp->tx_interval = htonl (tx_interval);
21331   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21332   vec_free (sys_name);
21333
21334   S (mp);
21335   W (ret);
21336   return ret;
21337 }
21338
21339 static int
21340 api_sw_interface_set_lldp (vat_main_t * vam)
21341 {
21342   unformat_input_t *i = vam->input;
21343   vl_api_sw_interface_set_lldp_t *mp;
21344   u32 sw_if_index = ~0;
21345   u32 enable = 1;
21346   u8 *port_desc = NULL, *mgmt_oid = NULL;
21347   ip4_address_t ip4_addr;
21348   ip6_address_t ip6_addr;
21349   int ret;
21350
21351   memset (&ip4_addr, 0, sizeof (ip4_addr));
21352   memset (&ip6_addr, 0, sizeof (ip6_addr));
21353
21354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21355     {
21356       if (unformat (i, "disable"))
21357         enable = 0;
21358       else
21359         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21360         ;
21361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21362         ;
21363       else if (unformat (i, "port-desc %s", &port_desc))
21364         ;
21365       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21366         ;
21367       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21368         ;
21369       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21370         ;
21371       else
21372         break;
21373     }
21374
21375   if (sw_if_index == ~0)
21376     {
21377       errmsg ("missing interface name or sw_if_index");
21378       return -99;
21379     }
21380
21381   /* Construct the API message */
21382   vec_add1 (port_desc, 0);
21383   vec_add1 (mgmt_oid, 0);
21384   M (SW_INTERFACE_SET_LLDP, mp);
21385   mp->sw_if_index = ntohl (sw_if_index);
21386   mp->enable = enable;
21387   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21388   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21389   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21390   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21391   vec_free (port_desc);
21392   vec_free (mgmt_oid);
21393
21394   S (mp);
21395   W (ret);
21396   return ret;
21397 }
21398
21399 static int
21400 api_tcp_configure_src_addresses (vat_main_t * vam)
21401 {
21402   vl_api_tcp_configure_src_addresses_t *mp;
21403   unformat_input_t *i = vam->input;
21404   ip4_address_t v4first, v4last;
21405   ip6_address_t v6first, v6last;
21406   u8 range_set = 0;
21407   u32 vrf_id = 0;
21408   int ret;
21409
21410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21411     {
21412       if (unformat (i, "%U - %U",
21413                     unformat_ip4_address, &v4first,
21414                     unformat_ip4_address, &v4last))
21415         {
21416           if (range_set)
21417             {
21418               errmsg ("one range per message (range already set)");
21419               return -99;
21420             }
21421           range_set = 1;
21422         }
21423       else if (unformat (i, "%U - %U",
21424                          unformat_ip6_address, &v6first,
21425                          unformat_ip6_address, &v6last))
21426         {
21427           if (range_set)
21428             {
21429               errmsg ("one range per message (range already set)");
21430               return -99;
21431             }
21432           range_set = 2;
21433         }
21434       else if (unformat (i, "vrf %d", &vrf_id))
21435         ;
21436       else
21437         break;
21438     }
21439
21440   if (range_set == 0)
21441     {
21442       errmsg ("address range not set");
21443       return -99;
21444     }
21445
21446   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21447   mp->vrf_id = ntohl (vrf_id);
21448   /* ipv6? */
21449   if (range_set == 2)
21450     {
21451       mp->is_ipv6 = 1;
21452       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21453       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21454     }
21455   else
21456     {
21457       mp->is_ipv6 = 0;
21458       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21459       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21460     }
21461   S (mp);
21462   W (ret);
21463   return ret;
21464 }
21465
21466 static int
21467 api_app_namespace_add_del (vat_main_t * vam)
21468 {
21469   vl_api_app_namespace_add_del_t *mp;
21470   unformat_input_t *i = vam->input;
21471   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21472   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21473   u64 secret;
21474   int ret;
21475
21476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21477     {
21478       if (unformat (i, "id %_%v%_", &ns_id))
21479         ;
21480       else if (unformat (i, "secret %lu", &secret))
21481         secret_set = 1;
21482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21483         sw_if_index_set = 1;
21484       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21485         ;
21486       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21487         ;
21488       else
21489         break;
21490     }
21491   if (!ns_id || !secret_set || !sw_if_index_set)
21492     {
21493       errmsg ("namespace id, secret and sw_if_index must be set");
21494       return -99;
21495     }
21496   if (vec_len (ns_id) > 64)
21497     {
21498       errmsg ("namespace id too long");
21499       return -99;
21500     }
21501   M (APP_NAMESPACE_ADD_DEL, mp);
21502
21503   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21504   mp->namespace_id_len = vec_len (ns_id);
21505   mp->secret = clib_host_to_net_u64 (secret);
21506   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21507   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21508   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21509   vec_free (ns_id);
21510   S (mp);
21511   W (ret);
21512   return ret;
21513 }
21514
21515 static int
21516 api_memfd_segment_create (vat_main_t * vam)
21517 {
21518 #if VPP_API_TEST_BUILTIN == 0
21519   unformat_input_t *i = vam->input;
21520   vl_api_memfd_segment_create_t *mp;
21521   u64 size = 64 << 20;
21522   int ret;
21523
21524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21525     {
21526       if (unformat (i, "size %U", unformat_memory_size, &size))
21527         ;
21528       else
21529         break;
21530     }
21531
21532   M (MEMFD_SEGMENT_CREATE, mp);
21533   mp->requested_size = size;
21534   S (mp);
21535   W (ret);
21536   return ret;
21537
21538 #else
21539   errmsg ("memfd_segment_create (builtin) not supported");
21540   return -99;
21541 #endif
21542 }
21543
21544 static int
21545 api_dns_enable_disable (vat_main_t * vam)
21546 {
21547   unformat_input_t *line_input = vam->input;
21548   vl_api_dns_enable_disable_t *mp;
21549   u8 enable_disable = 1;
21550   int ret;
21551
21552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21553     {
21554       if (unformat (line_input, "disable"))
21555         enable_disable = 0;
21556       if (unformat (line_input, "enable"))
21557         enable_disable = 1;
21558       else
21559         break;
21560     }
21561
21562   /* Construct the API message */
21563   M (DNS_ENABLE_DISABLE, mp);
21564   mp->enable = enable_disable;
21565
21566   /* send it... */
21567   S (mp);
21568   /* Wait for the reply */
21569   W (ret);
21570   return ret;
21571 }
21572
21573 static int
21574 api_dns_resolve_name (vat_main_t * vam)
21575 {
21576   unformat_input_t *line_input = vam->input;
21577   vl_api_dns_resolve_name_t *mp;
21578   u8 *name = 0;
21579   int ret;
21580
21581   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21582     {
21583       if (unformat (line_input, "%s", &name))
21584         ;
21585       else
21586         break;
21587     }
21588
21589   if (vec_len (name) > 127)
21590     {
21591       errmsg ("name too long");
21592       return -99;
21593     }
21594
21595   /* Construct the API message */
21596   M (DNS_RESOLVE_NAME, mp);
21597   memcpy (mp->name, name, vec_len (name));
21598   vec_free (name);
21599
21600   /* send it... */
21601   S (mp);
21602   /* Wait for the reply */
21603   W (ret);
21604   return ret;
21605 }
21606
21607 static int
21608 api_dns_resolve_ip (vat_main_t * vam)
21609 {
21610   unformat_input_t *line_input = vam->input;
21611   vl_api_dns_resolve_ip_t *mp;
21612   int is_ip6 = -1;
21613   ip4_address_t addr4;
21614   ip6_address_t addr6;
21615   int ret;
21616
21617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21618     {
21619       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21620         is_ip6 = 1;
21621       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21622         is_ip6 = 0;
21623       else
21624         break;
21625     }
21626
21627   if (is_ip6 == -1)
21628     {
21629       errmsg ("missing address");
21630       return -99;
21631     }
21632
21633   /* Construct the API message */
21634   M (DNS_RESOLVE_IP, mp);
21635   mp->is_ip6 = is_ip6;
21636   if (is_ip6)
21637     memcpy (mp->address, &addr6, sizeof (addr6));
21638   else
21639     memcpy (mp->address, &addr4, sizeof (addr4));
21640
21641   /* send it... */
21642   S (mp);
21643   /* Wait for the reply */
21644   W (ret);
21645   return ret;
21646 }
21647
21648 static int
21649 api_dns_name_server_add_del (vat_main_t * vam)
21650 {
21651   unformat_input_t *i = vam->input;
21652   vl_api_dns_name_server_add_del_t *mp;
21653   u8 is_add = 1;
21654   ip6_address_t ip6_server;
21655   ip4_address_t ip4_server;
21656   int ip6_set = 0;
21657   int ip4_set = 0;
21658   int ret = 0;
21659
21660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21661     {
21662       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21663         ip6_set = 1;
21664       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21665         ip4_set = 1;
21666       else if (unformat (i, "del"))
21667         is_add = 0;
21668       else
21669         {
21670           clib_warning ("parse error '%U'", format_unformat_error, i);
21671           return -99;
21672         }
21673     }
21674
21675   if (ip4_set && ip6_set)
21676     {
21677       errmsg ("Only one server address allowed per message");
21678       return -99;
21679     }
21680   if ((ip4_set + ip6_set) == 0)
21681     {
21682       errmsg ("Server address required");
21683       return -99;
21684     }
21685
21686   /* Construct the API message */
21687   M (DNS_NAME_SERVER_ADD_DEL, mp);
21688
21689   if (ip6_set)
21690     {
21691       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21692       mp->is_ip6 = 1;
21693     }
21694   else
21695     {
21696       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21697       mp->is_ip6 = 0;
21698     }
21699
21700   mp->is_add = is_add;
21701
21702   /* send it... */
21703   S (mp);
21704
21705   /* Wait for a reply, return good/bad news  */
21706   W (ret);
21707   return ret;
21708 }
21709
21710 static void
21711 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21712 {
21713   vat_main_t *vam = &vat_main;
21714
21715   if (mp->is_ip4)
21716     {
21717       print (vam->ofp,
21718              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21719              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21720              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21721              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21722              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21723              clib_net_to_host_u32 (mp->action_index), mp->tag);
21724     }
21725   else
21726     {
21727       print (vam->ofp,
21728              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21729              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21730              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21731              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21732              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21733              clib_net_to_host_u32 (mp->action_index), mp->tag);
21734     }
21735 }
21736
21737 static void
21738 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21739                                              mp)
21740 {
21741   vat_main_t *vam = &vat_main;
21742   vat_json_node_t *node = NULL;
21743   struct in6_addr ip6;
21744   struct in_addr ip4;
21745
21746   if (VAT_JSON_ARRAY != vam->json_tree.type)
21747     {
21748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21749       vat_json_init_array (&vam->json_tree);
21750     }
21751   node = vat_json_array_add (&vam->json_tree);
21752   vat_json_init_object (node);
21753
21754   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21755   vat_json_object_add_uint (node, "appns_index",
21756                             clib_net_to_host_u32 (mp->appns_index));
21757   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21758   vat_json_object_add_uint (node, "scope", mp->scope);
21759   vat_json_object_add_uint (node, "action_index",
21760                             clib_net_to_host_u32 (mp->action_index));
21761   vat_json_object_add_uint (node, "lcl_port",
21762                             clib_net_to_host_u16 (mp->lcl_port));
21763   vat_json_object_add_uint (node, "rmt_port",
21764                             clib_net_to_host_u16 (mp->rmt_port));
21765   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21766   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21767   vat_json_object_add_string_copy (node, "tag", mp->tag);
21768   if (mp->is_ip4)
21769     {
21770       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21771       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21772       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21773       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21774     }
21775   else
21776     {
21777       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21778       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21779       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21780       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21781     }
21782 }
21783
21784 static int
21785 api_session_rule_add_del (vat_main_t * vam)
21786 {
21787   vl_api_session_rule_add_del_t *mp;
21788   unformat_input_t *i = vam->input;
21789   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21790   u32 appns_index = 0, scope = 0;
21791   ip4_address_t lcl_ip4, rmt_ip4;
21792   ip6_address_t lcl_ip6, rmt_ip6;
21793   u8 is_ip4 = 1, conn_set = 0;
21794   u8 is_add = 1, *tag = 0;
21795   int ret;
21796
21797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21798     {
21799       if (unformat (i, "del"))
21800         is_add = 0;
21801       else if (unformat (i, "add"))
21802         ;
21803       else if (unformat (i, "proto tcp"))
21804         proto = 0;
21805       else if (unformat (i, "proto udp"))
21806         proto = 1;
21807       else if (unformat (i, "appns %d", &appns_index))
21808         ;
21809       else if (unformat (i, "scope %d", &scope))
21810         ;
21811       else if (unformat (i, "tag %_%v%_", &tag))
21812         ;
21813       else
21814         if (unformat
21815             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21816              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21817              &rmt_port))
21818         {
21819           is_ip4 = 1;
21820           conn_set = 1;
21821         }
21822       else
21823         if (unformat
21824             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21825              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21826              &rmt_port))
21827         {
21828           is_ip4 = 0;
21829           conn_set = 1;
21830         }
21831       else if (unformat (i, "action %d", &action))
21832         ;
21833       else
21834         break;
21835     }
21836   if (proto == ~0 || !conn_set || action == ~0)
21837     {
21838       errmsg ("transport proto, connection and action must be set");
21839       return -99;
21840     }
21841
21842   if (scope > 3)
21843     {
21844       errmsg ("scope should be 0-3");
21845       return -99;
21846     }
21847
21848   M (SESSION_RULE_ADD_DEL, mp);
21849
21850   mp->is_ip4 = is_ip4;
21851   mp->transport_proto = proto;
21852   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21853   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21854   mp->lcl_plen = lcl_plen;
21855   mp->rmt_plen = rmt_plen;
21856   mp->action_index = clib_host_to_net_u32 (action);
21857   mp->appns_index = clib_host_to_net_u32 (appns_index);
21858   mp->scope = scope;
21859   mp->is_add = is_add;
21860   if (is_ip4)
21861     {
21862       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21863       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21864     }
21865   else
21866     {
21867       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21868       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21869     }
21870   if (tag)
21871     {
21872       clib_memcpy (mp->tag, tag, vec_len (tag));
21873       vec_free (tag);
21874     }
21875
21876   S (mp);
21877   W (ret);
21878   return ret;
21879 }
21880
21881 static int
21882 api_session_rules_dump (vat_main_t * vam)
21883 {
21884   vl_api_session_rules_dump_t *mp;
21885   vl_api_control_ping_t *mp_ping;
21886   int ret;
21887
21888   if (!vam->json_output)
21889     {
21890       print (vam->ofp, "%=20s", "Session Rules");
21891     }
21892
21893   M (SESSION_RULES_DUMP, mp);
21894   /* send it... */
21895   S (mp);
21896
21897   /* Use a control ping for synchronization */
21898   MPING (CONTROL_PING, mp_ping);
21899   S (mp_ping);
21900
21901   /* Wait for a reply... */
21902   W (ret);
21903   return ret;
21904 }
21905
21906 static int
21907 api_ip_container_proxy_add_del (vat_main_t * vam)
21908 {
21909   vl_api_ip_container_proxy_add_del_t *mp;
21910   unformat_input_t *i = vam->input;
21911   u32 plen = ~0, sw_if_index = ~0;
21912   ip4_address_t ip4;
21913   ip6_address_t ip6;
21914   u8 is_ip4 = 1;
21915   u8 is_add = 1;
21916   int ret;
21917
21918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21919     {
21920       if (unformat (i, "del"))
21921         is_add = 0;
21922       else if (unformat (i, "add"))
21923         ;
21924       if (unformat (i, "%U", unformat_ip4_address, &ip4))
21925         {
21926           is_ip4 = 1;
21927           plen = 32;
21928         }
21929       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
21930         {
21931           is_ip4 = 0;
21932           plen = 128;
21933         }
21934       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21935         ;
21936       else
21937         break;
21938     }
21939   if (sw_if_index == ~0 || plen == ~0)
21940     {
21941       errmsg ("address and sw_if_index must be set");
21942       return -99;
21943     }
21944
21945   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21946
21947   mp->is_ip4 = is_ip4;
21948   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21949   mp->plen = plen;
21950   mp->is_add = is_add;
21951   if (is_ip4)
21952     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
21953   else
21954     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
21955
21956   S (mp);
21957   W (ret);
21958   return ret;
21959 }
21960
21961 static int
21962 q_or_quit (vat_main_t * vam)
21963 {
21964 #if VPP_API_TEST_BUILTIN == 0
21965   longjmp (vam->jump_buf, 1);
21966 #endif
21967   return 0;                     /* not so much */
21968 }
21969
21970 static int
21971 q (vat_main_t * vam)
21972 {
21973   return q_or_quit (vam);
21974 }
21975
21976 static int
21977 quit (vat_main_t * vam)
21978 {
21979   return q_or_quit (vam);
21980 }
21981
21982 static int
21983 comment (vat_main_t * vam)
21984 {
21985   return 0;
21986 }
21987
21988 static int
21989 cmd_cmp (void *a1, void *a2)
21990 {
21991   u8 **c1 = a1;
21992   u8 **c2 = a2;
21993
21994   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21995 }
21996
21997 static int
21998 help (vat_main_t * vam)
21999 {
22000   u8 **cmds = 0;
22001   u8 *name = 0;
22002   hash_pair_t *p;
22003   unformat_input_t *i = vam->input;
22004   int j;
22005
22006   if (unformat (i, "%s", &name))
22007     {
22008       uword *hs;
22009
22010       vec_add1 (name, 0);
22011
22012       hs = hash_get_mem (vam->help_by_name, name);
22013       if (hs)
22014         print (vam->ofp, "usage: %s %s", name, hs[0]);
22015       else
22016         print (vam->ofp, "No such msg / command '%s'", name);
22017       vec_free (name);
22018       return 0;
22019     }
22020
22021   print (vam->ofp, "Help is available for the following:");
22022
22023     /* *INDENT-OFF* */
22024     hash_foreach_pair (p, vam->function_by_name,
22025     ({
22026       vec_add1 (cmds, (u8 *)(p->key));
22027     }));
22028     /* *INDENT-ON* */
22029
22030   vec_sort_with_function (cmds, cmd_cmp);
22031
22032   for (j = 0; j < vec_len (cmds); j++)
22033     print (vam->ofp, "%s", cmds[j]);
22034
22035   vec_free (cmds);
22036   return 0;
22037 }
22038
22039 static int
22040 set (vat_main_t * vam)
22041 {
22042   u8 *name = 0, *value = 0;
22043   unformat_input_t *i = vam->input;
22044
22045   if (unformat (i, "%s", &name))
22046     {
22047       /* The input buffer is a vector, not a string. */
22048       value = vec_dup (i->buffer);
22049       vec_delete (value, i->index, 0);
22050       /* Almost certainly has a trailing newline */
22051       if (value[vec_len (value) - 1] == '\n')
22052         value[vec_len (value) - 1] = 0;
22053       /* Make sure it's a proper string, one way or the other */
22054       vec_add1 (value, 0);
22055       (void) clib_macro_set_value (&vam->macro_main,
22056                                    (char *) name, (char *) value);
22057     }
22058   else
22059     errmsg ("usage: set <name> <value>");
22060
22061   vec_free (name);
22062   vec_free (value);
22063   return 0;
22064 }
22065
22066 static int
22067 unset (vat_main_t * vam)
22068 {
22069   u8 *name = 0;
22070
22071   if (unformat (vam->input, "%s", &name))
22072     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22073       errmsg ("unset: %s wasn't set", name);
22074   vec_free (name);
22075   return 0;
22076 }
22077
22078 typedef struct
22079 {
22080   u8 *name;
22081   u8 *value;
22082 } macro_sort_t;
22083
22084
22085 static int
22086 macro_sort_cmp (void *a1, void *a2)
22087 {
22088   macro_sort_t *s1 = a1;
22089   macro_sort_t *s2 = a2;
22090
22091   return strcmp ((char *) (s1->name), (char *) (s2->name));
22092 }
22093
22094 static int
22095 dump_macro_table (vat_main_t * vam)
22096 {
22097   macro_sort_t *sort_me = 0, *sm;
22098   int i;
22099   hash_pair_t *p;
22100
22101     /* *INDENT-OFF* */
22102     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22103     ({
22104       vec_add2 (sort_me, sm, 1);
22105       sm->name = (u8 *)(p->key);
22106       sm->value = (u8 *) (p->value[0]);
22107     }));
22108     /* *INDENT-ON* */
22109
22110   vec_sort_with_function (sort_me, macro_sort_cmp);
22111
22112   if (vec_len (sort_me))
22113     print (vam->ofp, "%-15s%s", "Name", "Value");
22114   else
22115     print (vam->ofp, "The macro table is empty...");
22116
22117   for (i = 0; i < vec_len (sort_me); i++)
22118     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22119   return 0;
22120 }
22121
22122 static int
22123 dump_node_table (vat_main_t * vam)
22124 {
22125   int i, j;
22126   vlib_node_t *node, *next_node;
22127
22128   if (vec_len (vam->graph_nodes) == 0)
22129     {
22130       print (vam->ofp, "Node table empty, issue get_node_graph...");
22131       return 0;
22132     }
22133
22134   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22135     {
22136       node = vam->graph_nodes[i];
22137       print (vam->ofp, "[%d] %s", i, node->name);
22138       for (j = 0; j < vec_len (node->next_nodes); j++)
22139         {
22140           if (node->next_nodes[j] != ~0)
22141             {
22142               next_node = vam->graph_nodes[node->next_nodes[j]];
22143               print (vam->ofp, "  [%d] %s", j, next_node->name);
22144             }
22145         }
22146     }
22147   return 0;
22148 }
22149
22150 static int
22151 value_sort_cmp (void *a1, void *a2)
22152 {
22153   name_sort_t *n1 = a1;
22154   name_sort_t *n2 = a2;
22155
22156   if (n1->value < n2->value)
22157     return -1;
22158   if (n1->value > n2->value)
22159     return 1;
22160   return 0;
22161 }
22162
22163
22164 static int
22165 dump_msg_api_table (vat_main_t * vam)
22166 {
22167   api_main_t *am = &api_main;
22168   name_sort_t *nses = 0, *ns;
22169   hash_pair_t *hp;
22170   int i;
22171
22172   /* *INDENT-OFF* */
22173   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22174   ({
22175     vec_add2 (nses, ns, 1);
22176     ns->name = (u8 *)(hp->key);
22177     ns->value = (u32) hp->value[0];
22178   }));
22179   /* *INDENT-ON* */
22180
22181   vec_sort_with_function (nses, value_sort_cmp);
22182
22183   for (i = 0; i < vec_len (nses); i++)
22184     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22185   vec_free (nses);
22186   return 0;
22187 }
22188
22189 static int
22190 get_msg_id (vat_main_t * vam)
22191 {
22192   u8 *name_and_crc;
22193   u32 message_index;
22194
22195   if (unformat (vam->input, "%s", &name_and_crc))
22196     {
22197       message_index = vl_api_get_msg_index (name_and_crc);
22198       if (message_index == ~0)
22199         {
22200           print (vam->ofp, " '%s' not found", name_and_crc);
22201           return 0;
22202         }
22203       print (vam->ofp, " '%s' has message index %d",
22204              name_and_crc, message_index);
22205       return 0;
22206     }
22207   errmsg ("name_and_crc required...");
22208   return 0;
22209 }
22210
22211 static int
22212 search_node_table (vat_main_t * vam)
22213 {
22214   unformat_input_t *line_input = vam->input;
22215   u8 *node_to_find;
22216   int j;
22217   vlib_node_t *node, *next_node;
22218   uword *p;
22219
22220   if (vam->graph_node_index_by_name == 0)
22221     {
22222       print (vam->ofp, "Node table empty, issue get_node_graph...");
22223       return 0;
22224     }
22225
22226   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22227     {
22228       if (unformat (line_input, "%s", &node_to_find))
22229         {
22230           vec_add1 (node_to_find, 0);
22231           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22232           if (p == 0)
22233             {
22234               print (vam->ofp, "%s not found...", node_to_find);
22235               goto out;
22236             }
22237           node = vam->graph_nodes[p[0]];
22238           print (vam->ofp, "[%d] %s", p[0], node->name);
22239           for (j = 0; j < vec_len (node->next_nodes); j++)
22240             {
22241               if (node->next_nodes[j] != ~0)
22242                 {
22243                   next_node = vam->graph_nodes[node->next_nodes[j]];
22244                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22245                 }
22246             }
22247         }
22248
22249       else
22250         {
22251           clib_warning ("parse error '%U'", format_unformat_error,
22252                         line_input);
22253           return -99;
22254         }
22255
22256     out:
22257       vec_free (node_to_find);
22258
22259     }
22260
22261   return 0;
22262 }
22263
22264
22265 static int
22266 script (vat_main_t * vam)
22267 {
22268 #if (VPP_API_TEST_BUILTIN==0)
22269   u8 *s = 0;
22270   char *save_current_file;
22271   unformat_input_t save_input;
22272   jmp_buf save_jump_buf;
22273   u32 save_line_number;
22274
22275   FILE *new_fp, *save_ifp;
22276
22277   if (unformat (vam->input, "%s", &s))
22278     {
22279       new_fp = fopen ((char *) s, "r");
22280       if (new_fp == 0)
22281         {
22282           errmsg ("Couldn't open script file %s", s);
22283           vec_free (s);
22284           return -99;
22285         }
22286     }
22287   else
22288     {
22289       errmsg ("Missing script name");
22290       return -99;
22291     }
22292
22293   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22294   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22295   save_ifp = vam->ifp;
22296   save_line_number = vam->input_line_number;
22297   save_current_file = (char *) vam->current_file;
22298
22299   vam->input_line_number = 0;
22300   vam->ifp = new_fp;
22301   vam->current_file = s;
22302   do_one_file (vam);
22303
22304   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22305   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22306   vam->ifp = save_ifp;
22307   vam->input_line_number = save_line_number;
22308   vam->current_file = (u8 *) save_current_file;
22309   vec_free (s);
22310
22311   return 0;
22312 #else
22313   clib_warning ("use the exec command...");
22314   return -99;
22315 #endif
22316 }
22317
22318 static int
22319 echo (vat_main_t * vam)
22320 {
22321   print (vam->ofp, "%v", vam->input->buffer);
22322   return 0;
22323 }
22324
22325 /* List of API message constructors, CLI names map to api_xxx */
22326 #define foreach_vpe_api_msg                                             \
22327 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22328 _(sw_interface_dump,"")                                                 \
22329 _(sw_interface_set_flags,                                               \
22330   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22331 _(sw_interface_add_del_address,                                         \
22332   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22333 _(sw_interface_set_rx_mode,                                             \
22334   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22335 _(sw_interface_set_table,                                               \
22336   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22337 _(sw_interface_set_mpls_enable,                                         \
22338   "<intfc> | sw_if_index [disable | dis]")                              \
22339 _(sw_interface_set_vpath,                                               \
22340   "<intfc> | sw_if_index <id> enable | disable")                        \
22341 _(sw_interface_set_vxlan_bypass,                                        \
22342   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22343 _(sw_interface_set_geneve_bypass,                                       \
22344   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22345 _(sw_interface_set_l2_xconnect,                                         \
22346   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22347   "enable | disable")                                                   \
22348 _(sw_interface_set_l2_bridge,                                           \
22349   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22350   "[shg <split-horizon-group>] [bvi]\n"                                 \
22351   "enable | disable")                                                   \
22352 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22353 _(bridge_domain_add_del,                                                \
22354   "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") \
22355 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22356 _(l2fib_add_del,                                                        \
22357   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22358 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22359 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22360 _(l2_flags,                                                             \
22361   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22362 _(bridge_flags,                                                         \
22363   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22364 _(tap_connect,                                                          \
22365   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22366 _(tap_modify,                                                           \
22367   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22368 _(tap_delete,                                                           \
22369   "<vpp-if-name> | sw_if_index <id>")                                   \
22370 _(sw_interface_tap_dump, "")                                            \
22371 _(ip_table_add_del,                                                     \
22372   "table-id <n> [ipv6]\n")                                              \
22373 _(ip_add_del_route,                                                     \
22374   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22375   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22376   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22377   "[multipath] [count <n>]")                                            \
22378 _(ip_mroute_add_del,                                                    \
22379   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22380   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22381 _(mpls_table_add_del,                                                   \
22382   "table-id <n>\n")                                                     \
22383 _(mpls_route_add_del,                                                   \
22384   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22385   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22386   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22387   "[multipath] [count <n>]")                                            \
22388 _(mpls_ip_bind_unbind,                                                  \
22389   "<label> <addr/len>")                                                 \
22390 _(mpls_tunnel_add_del,                                                  \
22391   " via <addr> [table-id <n>]\n"                                        \
22392   "sw_if_index <id>] [l2]  [del]")                                      \
22393 _(bier_table_add_del,                                                   \
22394   "<label> <sub-domain> <set> <bsl> [del]")                             \
22395 _(bier_route_add_del,                                                   \
22396   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22397   "[<intfc> | sw_if_index <id>]"                                        \
22398   "[weight <n>] [del] [multipath]")                                     \
22399 _(proxy_arp_add_del,                                                    \
22400   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22401 _(proxy_arp_intfc_enable_disable,                                       \
22402   "<intfc> | sw_if_index <id> enable | disable")                        \
22403 _(sw_interface_set_unnumbered,                                          \
22404   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22405 _(ip_neighbor_add_del,                                                  \
22406   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22407   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22408 _(reset_vrf, "vrf <id> [ipv6]")                                         \
22409 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22410 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22411   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22412   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22413   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22414 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22415 _(reset_fib, "vrf <n> [ipv6]")                                          \
22416 _(dhcp_proxy_config,                                                    \
22417   "svr <v46-address> src <v46-address>\n"                               \
22418    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22419 _(dhcp_proxy_set_vss,                                                   \
22420   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22421 _(dhcp_proxy_dump, "ip6")                                               \
22422 _(dhcp_client_config,                                                   \
22423   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22424 _(set_ip_flow_hash,                                                     \
22425   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22426 _(sw_interface_ip6_enable_disable,                                      \
22427   "<intfc> | sw_if_index <id> enable | disable")                        \
22428 _(sw_interface_ip6_set_link_local_address,                              \
22429   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22430 _(ip6nd_proxy_add_del,                                                  \
22431   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22432 _(ip6nd_proxy_dump, "")                                                 \
22433 _(sw_interface_ip6nd_ra_prefix,                                         \
22434   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22435   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22436   "[nolink] [isno]")                                                    \
22437 _(sw_interface_ip6nd_ra_config,                                         \
22438   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22439   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22440   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22441 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22442 _(l2_patch_add_del,                                                     \
22443   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22444   "enable | disable")                                                   \
22445 _(sr_localsid_add_del,                                                  \
22446   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22447   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22448 _(classify_add_del_table,                                               \
22449   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22450   " [del] [del-chain] mask <mask-value>\n"                              \
22451   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22452   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22453 _(classify_add_del_session,                                             \
22454   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22455   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22456   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22457   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22458 _(classify_set_interface_ip_table,                                      \
22459   "<intfc> | sw_if_index <nn> table <nn>")                              \
22460 _(classify_set_interface_l2_tables,                                     \
22461   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22462   "  [other-table <nn>]")                                               \
22463 _(get_node_index, "node <node-name")                                    \
22464 _(add_node_next, "node <node-name> next <next-node-name>")              \
22465 _(l2tpv3_create_tunnel,                                                 \
22466   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22467   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22468   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22469 _(l2tpv3_set_tunnel_cookies,                                            \
22470   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22471   "[new_remote_cookie <nn>]\n")                                         \
22472 _(l2tpv3_interface_enable_disable,                                      \
22473   "<intfc> | sw_if_index <nn> enable | disable")                        \
22474 _(l2tpv3_set_lookup_key,                                                \
22475   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22476 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22477 _(vxlan_add_del_tunnel,                                                 \
22478   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22479   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22480   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22481 _(geneve_add_del_tunnel,                                                \
22482   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22483   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22484   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22485 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22486 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22487 _(gre_add_del_tunnel,                                                   \
22488   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22489 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22490 _(l2_fib_clear_table, "")                                               \
22491 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22492 _(l2_interface_vlan_tag_rewrite,                                        \
22493   "<intfc> | sw_if_index <nn> \n"                                       \
22494   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22495   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22496 _(create_vhost_user_if,                                                 \
22497         "socket <filename> [server] [renumber <dev_instance>] "         \
22498         "[mac <mac_address>]")                                          \
22499 _(modify_vhost_user_if,                                                 \
22500         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22501         "[server] [renumber <dev_instance>]")                           \
22502 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22503 _(sw_interface_vhost_user_dump, "")                                     \
22504 _(show_version, "")                                                     \
22505 _(vxlan_gpe_add_del_tunnel,                                             \
22506   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22507   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22508   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22509   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22510 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22511 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22512 _(interface_name_renumber,                                              \
22513   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22514 _(input_acl_set_interface,                                              \
22515   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22516   "  [l2-table <nn>] [del]")                                            \
22517 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22518 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22519 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22520 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22521 _(ip_dump, "ipv4 | ipv6")                                               \
22522 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22523 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22524   "  spid_id <n> ")                                                     \
22525 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22526   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22527   "  integ_alg <alg> integ_key <hex>")                                  \
22528 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22529   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22530   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22531   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22532 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22533 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22534   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22535   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22536   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22537 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22538 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22539   "  <alg> <hex>\n")                                                    \
22540 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22541 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22542 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22543   "(auth_data 0x<data> | auth_data <data>)")                            \
22544 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22545   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22546 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22547   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22548   "(local|remote)")                                                     \
22549 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22550 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22551 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22552 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22553 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22554 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22555 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22556 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22557 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22558 _(delete_loopback,"sw_if_index <nn>")                                   \
22559 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22560 _(map_add_domain,                                                       \
22561   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22562   "ip6-src <ip6addr> "                                                  \
22563   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22564 _(map_del_domain, "index <n>")                                          \
22565 _(map_add_del_rule,                                                     \
22566   "index <n> psid <n> dst <ip6addr> [del]")                             \
22567 _(map_domain_dump, "")                                                  \
22568 _(map_rule_dump, "index <map-domain>")                                  \
22569 _(want_interface_events,  "enable|disable")                             \
22570 _(want_stats,"enable|disable")                                          \
22571 _(get_first_msg_id, "client <name>")                                    \
22572 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22573 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22574   "fib-id <nn> [ip4][ip6][default]")                                    \
22575 _(get_node_graph, " ")                                                  \
22576 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22577 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22578 _(ioam_disable, "")                                                     \
22579 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22580                             " sw_if_index <sw_if_index> p <priority> "  \
22581                             "w <weight>] [del]")                        \
22582 _(one_add_del_locator, "locator-set <locator_name> "                    \
22583                         "iface <intf> | sw_if_index <sw_if_index> "     \
22584                         "p <priority> w <weight> [del]")                \
22585 _(one_add_del_local_eid,"vni <vni> eid "                                \
22586                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22587                          "locator-set <locator_name> [del]"             \
22588                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22589 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22590 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22591 _(one_enable_disable, "enable|disable")                                 \
22592 _(one_map_register_enable_disable, "enable|disable")                    \
22593 _(one_map_register_fallback_threshold, "<value>")                       \
22594 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22595 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22596                                "[seid <seid>] "                         \
22597                                "rloc <locator> p <prio> "               \
22598                                "w <weight> [rloc <loc> ... ] "          \
22599                                "action <action> [del-all]")             \
22600 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22601                           "<local-eid>")                                \
22602 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22603 _(one_use_petr, "ip-address> | disable")                                \
22604 _(one_map_request_mode, "src-dst|dst-only")                             \
22605 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22606 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22607 _(one_locator_set_dump, "[local | remote]")                             \
22608 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22609 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22610                        "[local] | [remote]")                            \
22611 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22612 _(one_ndp_bd_get, "")                                                   \
22613 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22614 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22615 _(one_l2_arp_bd_get, "")                                                \
22616 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22617 _(one_stats_enable_disable, "enable|disalbe")                           \
22618 _(show_one_stats_enable_disable, "")                                    \
22619 _(one_eid_table_vni_dump, "")                                           \
22620 _(one_eid_table_map_dump, "l2|l3")                                      \
22621 _(one_map_resolver_dump, "")                                            \
22622 _(one_map_server_dump, "")                                              \
22623 _(one_adjacencies_get, "vni <vni>")                                     \
22624 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22625 _(show_one_rloc_probe_state, "")                                        \
22626 _(show_one_map_register_state, "")                                      \
22627 _(show_one_status, "")                                                  \
22628 _(one_stats_dump, "")                                                   \
22629 _(one_stats_flush, "")                                                  \
22630 _(one_get_map_request_itr_rlocs, "")                                    \
22631 _(one_map_register_set_ttl, "<ttl>")                                    \
22632 _(one_set_transport_protocol, "udp|api")                                \
22633 _(one_get_transport_protocol, "")                                       \
22634 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22635 _(one_show_xtr_mode, "")                                                \
22636 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22637 _(one_show_pitr_mode, "")                                               \
22638 _(one_enable_disable_petr_mode, "enable|disable")                       \
22639 _(one_show_petr_mode, "")                                               \
22640 _(show_one_nsh_mapping, "")                                             \
22641 _(show_one_pitr, "")                                                    \
22642 _(show_one_use_petr, "")                                                \
22643 _(show_one_map_request_mode, "")                                        \
22644 _(show_one_map_register_ttl, "")                                        \
22645 _(show_one_map_register_fallback_threshold, "")                         \
22646 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22647                             " sw_if_index <sw_if_index> p <priority> "  \
22648                             "w <weight>] [del]")                        \
22649 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22650                         "iface <intf> | sw_if_index <sw_if_index> "     \
22651                         "p <priority> w <weight> [del]")                \
22652 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22653                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22654                          "locator-set <locator_name> [del]"             \
22655                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22656 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22657 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22658 _(lisp_enable_disable, "enable|disable")                                \
22659 _(lisp_map_register_enable_disable, "enable|disable")                   \
22660 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22661 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22662                                "[seid <seid>] "                         \
22663                                "rloc <locator> p <prio> "               \
22664                                "w <weight> [rloc <loc> ... ] "          \
22665                                "action <action> [del-all]")             \
22666 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22667                           "<local-eid>")                                \
22668 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22669 _(lisp_use_petr, "<ip-address> | disable")                              \
22670 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22671 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22672 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22673 _(lisp_locator_set_dump, "[local | remote]")                            \
22674 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22675 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22676                        "[local] | [remote]")                            \
22677 _(lisp_eid_table_vni_dump, "")                                          \
22678 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22679 _(lisp_map_resolver_dump, "")                                           \
22680 _(lisp_map_server_dump, "")                                             \
22681 _(lisp_adjacencies_get, "vni <vni>")                                    \
22682 _(gpe_fwd_entry_vnis_get, "")                                           \
22683 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22684 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22685                                 "[table <table-id>]")                   \
22686 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22687 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22688 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22689 _(gpe_get_encap_mode, "")                                               \
22690 _(lisp_gpe_add_del_iface, "up|down")                                    \
22691 _(lisp_gpe_enable_disable, "enable|disable")                            \
22692 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22693   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22694 _(show_lisp_rloc_probe_state, "")                                       \
22695 _(show_lisp_map_register_state, "")                                     \
22696 _(show_lisp_status, "")                                                 \
22697 _(lisp_get_map_request_itr_rlocs, "")                                   \
22698 _(show_lisp_pitr, "")                                                   \
22699 _(show_lisp_use_petr, "")                                               \
22700 _(show_lisp_map_request_mode, "")                                       \
22701 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22702 _(af_packet_delete, "name <host interface name>")                       \
22703 _(policer_add_del, "name <policer name> <params> [del]")                \
22704 _(policer_dump, "[name <policer name>]")                                \
22705 _(policer_classify_set_interface,                                       \
22706   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22707   "  [l2-table <nn>] [del]")                                            \
22708 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22709 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22710     "[master|slave]")                                                   \
22711 _(netmap_delete, "name <interface name>")                               \
22712 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22713 _(mpls_fib_dump, "")                                                    \
22714 _(classify_table_ids, "")                                               \
22715 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22716 _(classify_table_info, "table_id <nn>")                                 \
22717 _(classify_session_dump, "table_id <nn>")                               \
22718 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22719     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22720     "[template_interval <nn>] [udp_checksum]")                          \
22721 _(ipfix_exporter_dump, "")                                              \
22722 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22723 _(ipfix_classify_stream_dump, "")                                       \
22724 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22725 _(ipfix_classify_table_dump, "")                                        \
22726 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22727 _(sw_interface_span_dump, "[l2]")                                           \
22728 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22729 _(pg_create_interface, "if_id <nn>")                                    \
22730 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22731 _(pg_enable_disable, "[stream <id>] disable")                           \
22732 _(ip_source_and_port_range_check_add_del,                               \
22733   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22734 _(ip_source_and_port_range_check_interface_add_del,                     \
22735   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22736   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22737 _(ipsec_gre_add_del_tunnel,                                             \
22738   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22739 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22740 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22741 _(l2_interface_pbb_tag_rewrite,                                         \
22742   "<intfc> | sw_if_index <nn> \n"                                       \
22743   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22744   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22745 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22746 _(flow_classify_set_interface,                                          \
22747   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22748 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22749 _(ip_fib_dump, "")                                                      \
22750 _(ip_mfib_dump, "")                                                     \
22751 _(ip6_fib_dump, "")                                                     \
22752 _(ip6_mfib_dump, "")                                                    \
22753 _(feature_enable_disable, "arc_name <arc_name> "                        \
22754   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22755 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22756 "[disable]")                                                            \
22757 _(l2_xconnect_dump, "")                                                 \
22758 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22759 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22760 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22761 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22762 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22763 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22764 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22765   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22766 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22767 _(memfd_segment_create,"size <nnn>")                                    \
22768 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22769 _(dns_enable_disable, "[enable][disable]")                              \
22770 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22771 _(dns_resolve_name, "<hostname>")                                       \
22772 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22773 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22774 _(dns_resolve_name, "<hostname>")                                       \
22775 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22776   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22777 _(session_rules_dump, "")                                               \
22778 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22779
22780 /* List of command functions, CLI names map directly to functions */
22781 #define foreach_cli_function                                    \
22782 _(comment, "usage: comment <ignore-rest-of-line>")              \
22783 _(dump_interface_table, "usage: dump_interface_table")          \
22784 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22785 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22786 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22787 _(dump_stats_table, "usage: dump_stats_table")                  \
22788 _(dump_macro_table, "usage: dump_macro_table ")                 \
22789 _(dump_node_table, "usage: dump_node_table")                    \
22790 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22791 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22792 _(echo, "usage: echo <message>")                                \
22793 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22794 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22795 _(help, "usage: help")                                          \
22796 _(q, "usage: quit")                                             \
22797 _(quit, "usage: quit")                                          \
22798 _(search_node_table, "usage: search_node_table <name>...")      \
22799 _(set, "usage: set <variable-name> <value>")                    \
22800 _(script, "usage: script <file-name>")                          \
22801 _(unset, "usage: unset <variable-name>")
22802 #define _(N,n)                                  \
22803     static void vl_api_##n##_t_handler_uni      \
22804     (vl_api_##n##_t * mp)                       \
22805     {                                           \
22806         vat_main_t * vam = &vat_main;           \
22807         if (vam->json_output) {                 \
22808             vl_api_##n##_t_handler_json(mp);    \
22809         } else {                                \
22810             vl_api_##n##_t_handler(mp);         \
22811         }                                       \
22812     }
22813 foreach_vpe_api_reply_msg;
22814 #if VPP_API_TEST_BUILTIN == 0
22815 foreach_standalone_reply_msg;
22816 #endif
22817 #undef _
22818
22819 void
22820 vat_api_hookup (vat_main_t * vam)
22821 {
22822 #define _(N,n)                                                  \
22823     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22824                            vl_api_##n##_t_handler_uni,          \
22825                            vl_noop_handler,                     \
22826                            vl_api_##n##_t_endian,               \
22827                            vl_api_##n##_t_print,                \
22828                            sizeof(vl_api_##n##_t), 1);
22829   foreach_vpe_api_reply_msg;
22830 #if VPP_API_TEST_BUILTIN == 0
22831   foreach_standalone_reply_msg;
22832 #endif
22833 #undef _
22834
22835 #if (VPP_API_TEST_BUILTIN==0)
22836   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22837
22838   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22839
22840   vam->function_by_name = hash_create_string (0, sizeof (uword));
22841
22842   vam->help_by_name = hash_create_string (0, sizeof (uword));
22843 #endif
22844
22845   /* API messages we can send */
22846 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22847   foreach_vpe_api_msg;
22848 #undef _
22849
22850   /* Help strings */
22851 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22852   foreach_vpe_api_msg;
22853 #undef _
22854
22855   /* CLI functions */
22856 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22857   foreach_cli_function;
22858 #undef _
22859
22860   /* Help strings */
22861 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22862   foreach_cli_function;
22863 #undef _
22864 }
22865
22866 #if VPP_API_TEST_BUILTIN
22867 static clib_error_t *
22868 vat_api_hookup_shim (vlib_main_t * vm)
22869 {
22870   vat_api_hookup (&vat_main);
22871   return 0;
22872 }
22873
22874 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22875 #endif
22876
22877 /*
22878  * fd.io coding-style-patch-verification: ON
22879  *
22880  * Local Variables:
22881  * eval: (c-set-style "gnu")
22882  * End:
22883  */