LISP: add P-ITR/P-ETR/xTR API handlers, ONE-24
[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 _(proxy_arp_add_del_reply)                              \
5184 _(proxy_arp_intfc_enable_disable_reply)                 \
5185 _(sw_interface_set_unnumbered_reply)                    \
5186 _(ip_neighbor_add_del_reply)                            \
5187 _(reset_vrf_reply)                                      \
5188 _(oam_add_del_reply)                                    \
5189 _(reset_fib_reply)                                      \
5190 _(dhcp_proxy_config_reply)                              \
5191 _(dhcp_proxy_set_vss_reply)                             \
5192 _(dhcp_client_config_reply)                             \
5193 _(set_ip_flow_hash_reply)                               \
5194 _(sw_interface_ip6_enable_disable_reply)                \
5195 _(sw_interface_ip6_set_link_local_address_reply)        \
5196 _(ip6nd_proxy_add_del_reply)                            \
5197 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5198 _(sw_interface_ip6nd_ra_config_reply)                   \
5199 _(set_arp_neighbor_limit_reply)                         \
5200 _(l2_patch_add_del_reply)                               \
5201 _(sr_policy_add_reply)                                  \
5202 _(sr_policy_mod_reply)                                  \
5203 _(sr_policy_del_reply)                                  \
5204 _(sr_localsid_add_del_reply)                            \
5205 _(sr_steering_add_del_reply)                            \
5206 _(classify_add_del_session_reply)                       \
5207 _(classify_set_interface_ip_table_reply)                \
5208 _(classify_set_interface_l2_tables_reply)               \
5209 _(l2tpv3_set_tunnel_cookies_reply)                      \
5210 _(l2tpv3_interface_enable_disable_reply)                \
5211 _(l2tpv3_set_lookup_key_reply)                          \
5212 _(l2_fib_clear_table_reply)                             \
5213 _(l2_interface_efp_filter_reply)                        \
5214 _(l2_interface_vlan_tag_rewrite_reply)                  \
5215 _(modify_vhost_user_if_reply)                           \
5216 _(delete_vhost_user_if_reply)                           \
5217 _(want_ip4_arp_events_reply)                            \
5218 _(want_ip6_nd_events_reply)                             \
5219 _(want_l2_macs_events_reply)                            \
5220 _(input_acl_set_interface_reply)                        \
5221 _(ipsec_spd_add_del_reply)                              \
5222 _(ipsec_interface_add_del_spd_reply)                    \
5223 _(ipsec_spd_add_del_entry_reply)                        \
5224 _(ipsec_sad_add_del_entry_reply)                        \
5225 _(ipsec_sa_set_key_reply)                               \
5226 _(ipsec_tunnel_if_add_del_reply)                        \
5227 _(ipsec_tunnel_if_set_key_reply)                        \
5228 _(ipsec_tunnel_if_set_sa_reply)                         \
5229 _(ikev2_profile_add_del_reply)                          \
5230 _(ikev2_profile_set_auth_reply)                         \
5231 _(ikev2_profile_set_id_reply)                           \
5232 _(ikev2_profile_set_ts_reply)                           \
5233 _(ikev2_set_local_key_reply)                            \
5234 _(ikev2_set_responder_reply)                            \
5235 _(ikev2_set_ike_transforms_reply)                       \
5236 _(ikev2_set_esp_transforms_reply)                       \
5237 _(ikev2_set_sa_lifetime_reply)                          \
5238 _(ikev2_initiate_sa_init_reply)                         \
5239 _(ikev2_initiate_del_ike_sa_reply)                      \
5240 _(ikev2_initiate_del_child_sa_reply)                    \
5241 _(ikev2_initiate_rekey_child_sa_reply)                  \
5242 _(delete_loopback_reply)                                \
5243 _(bd_ip_mac_add_del_reply)                              \
5244 _(map_del_domain_reply)                                 \
5245 _(map_add_del_rule_reply)                               \
5246 _(want_interface_events_reply)                          \
5247 _(want_stats_reply)                                     \
5248 _(cop_interface_enable_disable_reply)                   \
5249 _(cop_whitelist_enable_disable_reply)                   \
5250 _(sw_interface_clear_stats_reply)                       \
5251 _(ioam_enable_reply)                                    \
5252 _(ioam_disable_reply)                                   \
5253 _(one_add_del_locator_reply)                            \
5254 _(one_add_del_local_eid_reply)                          \
5255 _(one_add_del_remote_mapping_reply)                     \
5256 _(one_add_del_adjacency_reply)                          \
5257 _(one_add_del_map_resolver_reply)                       \
5258 _(one_add_del_map_server_reply)                         \
5259 _(one_enable_disable_reply)                             \
5260 _(one_rloc_probe_enable_disable_reply)                  \
5261 _(one_map_register_enable_disable_reply)                \
5262 _(one_map_register_set_ttl_reply)                       \
5263 _(one_set_transport_protocol_reply)                     \
5264 _(one_map_register_fallback_threshold_reply)            \
5265 _(one_pitr_set_locator_set_reply)                       \
5266 _(one_map_request_mode_reply)                           \
5267 _(one_add_del_map_request_itr_rlocs_reply)              \
5268 _(one_eid_table_add_del_map_reply)                      \
5269 _(one_use_petr_reply)                                   \
5270 _(one_stats_enable_disable_reply)                       \
5271 _(one_add_del_l2_arp_entry_reply)                       \
5272 _(one_add_del_ndp_entry_reply)                          \
5273 _(one_stats_flush_reply)                                \
5274 _(one_enable_disable_xtr_mode_reply)                    \
5275 _(one_enable_disable_pitr_mode_reply)                   \
5276 _(one_enable_disable_petr_mode_reply)                   \
5277 _(gpe_enable_disable_reply)                             \
5278 _(gpe_set_encap_mode_reply)                             \
5279 _(gpe_add_del_iface_reply)                              \
5280 _(gpe_add_del_native_fwd_rpath_reply)                   \
5281 _(af_packet_delete_reply)                               \
5282 _(policer_classify_set_interface_reply)                 \
5283 _(netmap_create_reply)                                  \
5284 _(netmap_delete_reply)                                  \
5285 _(set_ipfix_exporter_reply)                             \
5286 _(set_ipfix_classify_stream_reply)                      \
5287 _(ipfix_classify_table_add_del_reply)                   \
5288 _(flow_classify_set_interface_reply)                    \
5289 _(sw_interface_span_enable_disable_reply)               \
5290 _(pg_capture_reply)                                     \
5291 _(pg_enable_disable_reply)                              \
5292 _(ip_source_and_port_range_check_add_del_reply)         \
5293 _(ip_source_and_port_range_check_interface_add_del_reply)\
5294 _(delete_subif_reply)                                   \
5295 _(l2_interface_pbb_tag_rewrite_reply)                   \
5296 _(punt_reply)                                           \
5297 _(feature_enable_disable_reply)                         \
5298 _(sw_interface_tag_add_del_reply)                       \
5299 _(sw_interface_set_mtu_reply)                           \
5300 _(p2p_ethernet_add_reply)                               \
5301 _(p2p_ethernet_del_reply)                               \
5302 _(lldp_config_reply)                                    \
5303 _(sw_interface_set_lldp_reply)                          \
5304 _(tcp_configure_src_addresses_reply)                    \
5305 _(app_namespace_add_del_reply)                          \
5306 _(dns_enable_disable_reply)                             \
5307 _(dns_name_server_add_del_reply)                        \
5308 _(session_rule_add_del_reply)
5309
5310 #define _(n)                                    \
5311     static void vl_api_##n##_t_handler          \
5312     (vl_api_##n##_t * mp)                       \
5313     {                                           \
5314         vat_main_t * vam = &vat_main;           \
5315         i32 retval = ntohl(mp->retval);         \
5316         if (vam->async_mode) {                  \
5317             vam->async_errors += (retval < 0);  \
5318         } else {                                \
5319             vam->retval = retval;               \
5320             vam->result_ready = 1;              \
5321         }                                       \
5322     }
5323 foreach_standard_reply_retval_handler;
5324 #undef _
5325
5326 #define _(n)                                    \
5327     static void vl_api_##n##_t_handler_json     \
5328     (vl_api_##n##_t * mp)                       \
5329     {                                           \
5330         vat_main_t * vam = &vat_main;           \
5331         vat_json_node_t node;                   \
5332         vat_json_init_object(&node);            \
5333         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5334         vat_json_print(vam->ofp, &node);        \
5335         vam->retval = ntohl(mp->retval);        \
5336         vam->result_ready = 1;                  \
5337     }
5338 foreach_standard_reply_retval_handler;
5339 #undef _
5340
5341 /*
5342  * Table of message reply handlers, must include boilerplate handlers
5343  * we just generated
5344  */
5345
5346 #define foreach_vpe_api_reply_msg                                       \
5347 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5348 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5349 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5350 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5351 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5352 _(CLI_REPLY, cli_reply)                                                 \
5353 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5354 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5355   sw_interface_add_del_address_reply)                                   \
5356 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5357 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5358 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5359 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5360 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5361 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5362 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5363 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5364   sw_interface_set_l2_xconnect_reply)                                   \
5365 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5366   sw_interface_set_l2_bridge_reply)                                     \
5367 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5368 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5369 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5370 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5371 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5372 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5373 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5374 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5375 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5376 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5377 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5378 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5379 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5380 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5381 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5382 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5383 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5384 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5385 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5386 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5387   proxy_arp_intfc_enable_disable_reply)                                 \
5388 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5389 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5390   sw_interface_set_unnumbered_reply)                                    \
5391 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5392 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5393 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5394 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5395 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5396 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5397 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5398 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5399 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5400 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5401 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5402 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5403   sw_interface_ip6_enable_disable_reply)                                \
5404 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5405   sw_interface_ip6_set_link_local_address_reply)                        \
5406 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5407 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5408 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5409   sw_interface_ip6nd_ra_prefix_reply)                                   \
5410 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5411   sw_interface_ip6nd_ra_config_reply)                                   \
5412 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5413 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5414 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5415 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5416 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5417 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5418 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5419 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5420 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5421 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5422 classify_set_interface_ip_table_reply)                                  \
5423 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5424   classify_set_interface_l2_tables_reply)                               \
5425 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5426 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5427 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5428 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5429 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5430   l2tpv3_interface_enable_disable_reply)                                \
5431 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5432 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5433 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5434 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5435 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5436 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5437 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5438 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5439 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5440 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5441 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5442 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5443 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5444 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5445 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5446 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5447 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5448 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5449 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5450 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5451 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5452 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5453 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5454 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5455 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5456 _(L2_MACS_EVENT, l2_macs_event)                                         \
5457 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5458 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5459 _(IP_DETAILS, ip_details)                                               \
5460 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5461 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5462 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5463 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5464 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5465 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5466 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5467 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5468 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5469 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5470 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5471 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5472 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5473 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5474 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5475 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5476 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5477 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5478 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5479 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5480 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5481 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5482 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5483 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5484 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5485 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5486 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5487 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5488 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5489 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5490 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5491 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5492 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5493 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5494 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5495 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5496 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5497 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5498 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5499 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5500 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5501 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5502 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5503 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5504 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5505 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5506 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5507 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5508   one_map_register_enable_disable_reply)                                \
5509 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5510 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5511 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5512 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5513   one_map_register_fallback_threshold_reply)                            \
5514 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5515   one_rloc_probe_enable_disable_reply)                                  \
5516 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5517 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5518 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5519 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5520 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5521 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5522 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5523 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5524 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5525 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5526 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5527 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5528 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5529 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5530 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5531 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5532   show_one_stats_enable_disable_reply)                                  \
5533 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5534 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5535 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5536 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5537 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5538 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5539 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5540 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5541   one_enable_disable_pitr_mode_reply)                                   \
5542 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5543   one_enable_disable_petr_mode_reply)                                   \
5544 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5545 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5546 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5547 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5548 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5549 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5550 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5551 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5552 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5553 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5554 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5555 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5556   gpe_add_del_native_fwd_rpath_reply)                                   \
5557 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5558   gpe_fwd_entry_path_details)                                           \
5559 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5560 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5561   one_add_del_map_request_itr_rlocs_reply)                              \
5562 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5563   one_get_map_request_itr_rlocs_reply)                                  \
5564 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5565 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5566 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5567 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5568 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5569 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5570   show_one_map_register_state_reply)                                    \
5571 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5572 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5573   show_one_map_register_fallback_threshold_reply)                       \
5574 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5575 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5576 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5577 _(POLICER_DETAILS, policer_details)                                     \
5578 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5579 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5580 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5581 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5582 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5583 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5584 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5585 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5586 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5587 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5588 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5589 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5590 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5591 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5592 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5593 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5594 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5595 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5596 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5597 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5598 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5599 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5600 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5601 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5602 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5603  ip_source_and_port_range_check_add_del_reply)                          \
5604 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5605  ip_source_and_port_range_check_interface_add_del_reply)                \
5606 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5607 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5608 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5609 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5610 _(PUNT_REPLY, punt_reply)                                               \
5611 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5612 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5613 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5614 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5615 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5616 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5617 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5618 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5619 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5620 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5621 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5622 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5623 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5624 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5625 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5626 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5627 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5628 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5629 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)
5630
5631 #define foreach_standalone_reply_msg                                    \
5632 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5633 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5634 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5635 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5636 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5637 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5638 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5639 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5640
5641 typedef struct
5642 {
5643   u8 *name;
5644   u32 value;
5645 } name_sort_t;
5646
5647
5648 #define STR_VTR_OP_CASE(op)     \
5649     case L2_VTR_ ## op:         \
5650         return "" # op;
5651
5652 static const char *
5653 str_vtr_op (u32 vtr_op)
5654 {
5655   switch (vtr_op)
5656     {
5657       STR_VTR_OP_CASE (DISABLED);
5658       STR_VTR_OP_CASE (PUSH_1);
5659       STR_VTR_OP_CASE (PUSH_2);
5660       STR_VTR_OP_CASE (POP_1);
5661       STR_VTR_OP_CASE (POP_2);
5662       STR_VTR_OP_CASE (TRANSLATE_1_1);
5663       STR_VTR_OP_CASE (TRANSLATE_1_2);
5664       STR_VTR_OP_CASE (TRANSLATE_2_1);
5665       STR_VTR_OP_CASE (TRANSLATE_2_2);
5666     }
5667
5668   return "UNKNOWN";
5669 }
5670
5671 static int
5672 dump_sub_interface_table (vat_main_t * vam)
5673 {
5674   const sw_interface_subif_t *sub = NULL;
5675
5676   if (vam->json_output)
5677     {
5678       clib_warning
5679         ("JSON output supported only for VPE API calls and dump_stats_table");
5680       return -99;
5681     }
5682
5683   print (vam->ofp,
5684          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5685          "Interface", "sw_if_index",
5686          "sub id", "dot1ad", "tags", "outer id",
5687          "inner id", "exact", "default", "outer any", "inner any");
5688
5689   vec_foreach (sub, vam->sw_if_subif_table)
5690   {
5691     print (vam->ofp,
5692            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5693            sub->interface_name,
5694            sub->sw_if_index,
5695            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5696            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5697            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5698            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5699     if (sub->vtr_op != L2_VTR_DISABLED)
5700       {
5701         print (vam->ofp,
5702                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5703                "tag1: %d tag2: %d ]",
5704                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5705                sub->vtr_tag1, sub->vtr_tag2);
5706       }
5707   }
5708
5709   return 0;
5710 }
5711
5712 static int
5713 name_sort_cmp (void *a1, void *a2)
5714 {
5715   name_sort_t *n1 = a1;
5716   name_sort_t *n2 = a2;
5717
5718   return strcmp ((char *) n1->name, (char *) n2->name);
5719 }
5720
5721 static int
5722 dump_interface_table (vat_main_t * vam)
5723 {
5724   hash_pair_t *p;
5725   name_sort_t *nses = 0, *ns;
5726
5727   if (vam->json_output)
5728     {
5729       clib_warning
5730         ("JSON output supported only for VPE API calls and dump_stats_table");
5731       return -99;
5732     }
5733
5734   /* *INDENT-OFF* */
5735   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5736   ({
5737     vec_add2 (nses, ns, 1);
5738     ns->name = (u8 *)(p->key);
5739     ns->value = (u32) p->value[0];
5740   }));
5741   /* *INDENT-ON* */
5742
5743   vec_sort_with_function (nses, name_sort_cmp);
5744
5745   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5746   vec_foreach (ns, nses)
5747   {
5748     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5749   }
5750   vec_free (nses);
5751   return 0;
5752 }
5753
5754 static int
5755 dump_ip_table (vat_main_t * vam, int is_ipv6)
5756 {
5757   const ip_details_t *det = NULL;
5758   const ip_address_details_t *address = NULL;
5759   u32 i = ~0;
5760
5761   print (vam->ofp, "%-12s", "sw_if_index");
5762
5763   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5764   {
5765     i++;
5766     if (!det->present)
5767       {
5768         continue;
5769       }
5770     print (vam->ofp, "%-12d", i);
5771     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5772     if (!det->addr)
5773       {
5774         continue;
5775       }
5776     vec_foreach (address, det->addr)
5777     {
5778       print (vam->ofp,
5779              "            %-30U%-13d",
5780              is_ipv6 ? format_ip6_address : format_ip4_address,
5781              address->ip, address->prefix_length);
5782     }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 dump_ipv4_table (vat_main_t * vam)
5790 {
5791   if (vam->json_output)
5792     {
5793       clib_warning
5794         ("JSON output supported only for VPE API calls and dump_stats_table");
5795       return -99;
5796     }
5797
5798   return dump_ip_table (vam, 0);
5799 }
5800
5801 static int
5802 dump_ipv6_table (vat_main_t * vam)
5803 {
5804   if (vam->json_output)
5805     {
5806       clib_warning
5807         ("JSON output supported only for VPE API calls and dump_stats_table");
5808       return -99;
5809     }
5810
5811   return dump_ip_table (vam, 1);
5812 }
5813
5814 static char *
5815 counter_type_to_str (u8 counter_type, u8 is_combined)
5816 {
5817   if (!is_combined)
5818     {
5819       switch (counter_type)
5820         {
5821         case VNET_INTERFACE_COUNTER_DROP:
5822           return "drop";
5823         case VNET_INTERFACE_COUNTER_PUNT:
5824           return "punt";
5825         case VNET_INTERFACE_COUNTER_IP4:
5826           return "ip4";
5827         case VNET_INTERFACE_COUNTER_IP6:
5828           return "ip6";
5829         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5830           return "rx-no-buf";
5831         case VNET_INTERFACE_COUNTER_RX_MISS:
5832           return "rx-miss";
5833         case VNET_INTERFACE_COUNTER_RX_ERROR:
5834           return "rx-error";
5835         case VNET_INTERFACE_COUNTER_TX_ERROR:
5836           return "tx-error";
5837         default:
5838           return "INVALID-COUNTER-TYPE";
5839         }
5840     }
5841   else
5842     {
5843       switch (counter_type)
5844         {
5845         case VNET_INTERFACE_COUNTER_RX:
5846           return "rx";
5847         case VNET_INTERFACE_COUNTER_TX:
5848           return "tx";
5849         default:
5850           return "INVALID-COUNTER-TYPE";
5851         }
5852     }
5853 }
5854
5855 static int
5856 dump_stats_table (vat_main_t * vam)
5857 {
5858   vat_json_node_t node;
5859   vat_json_node_t *msg_array;
5860   vat_json_node_t *msg;
5861   vat_json_node_t *counter_array;
5862   vat_json_node_t *counter;
5863   interface_counter_t c;
5864   u64 packets;
5865   ip4_fib_counter_t *c4;
5866   ip6_fib_counter_t *c6;
5867   ip4_nbr_counter_t *n4;
5868   ip6_nbr_counter_t *n6;
5869   int i, j;
5870
5871   if (!vam->json_output)
5872     {
5873       clib_warning ("dump_stats_table supported only in JSON format");
5874       return -99;
5875     }
5876
5877   vat_json_init_object (&node);
5878
5879   /* interface counters */
5880   msg_array = vat_json_object_add (&node, "interface_counters");
5881   vat_json_init_array (msg_array);
5882   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5883     {
5884       msg = vat_json_array_add (msg_array);
5885       vat_json_init_object (msg);
5886       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5887                                        (u8 *) counter_type_to_str (i, 0));
5888       vat_json_object_add_int (msg, "is_combined", 0);
5889       counter_array = vat_json_object_add (msg, "data");
5890       vat_json_init_array (counter_array);
5891       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5892         {
5893           packets = vam->simple_interface_counters[i][j];
5894           vat_json_array_add_uint (counter_array, packets);
5895         }
5896     }
5897   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5898     {
5899       msg = vat_json_array_add (msg_array);
5900       vat_json_init_object (msg);
5901       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5902                                        (u8 *) counter_type_to_str (i, 1));
5903       vat_json_object_add_int (msg, "is_combined", 1);
5904       counter_array = vat_json_object_add (msg, "data");
5905       vat_json_init_array (counter_array);
5906       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5907         {
5908           c = vam->combined_interface_counters[i][j];
5909           counter = vat_json_array_add (counter_array);
5910           vat_json_init_object (counter);
5911           vat_json_object_add_uint (counter, "packets", c.packets);
5912           vat_json_object_add_uint (counter, "bytes", c.bytes);
5913         }
5914     }
5915
5916   /* ip4 fib counters */
5917   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5918   vat_json_init_array (msg_array);
5919   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5920     {
5921       msg = vat_json_array_add (msg_array);
5922       vat_json_init_object (msg);
5923       vat_json_object_add_uint (msg, "vrf_id",
5924                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5925       counter_array = vat_json_object_add (msg, "c");
5926       vat_json_init_array (counter_array);
5927       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5928         {
5929           counter = vat_json_array_add (counter_array);
5930           vat_json_init_object (counter);
5931           c4 = &vam->ip4_fib_counters[i][j];
5932           vat_json_object_add_ip4 (counter, "address", c4->address);
5933           vat_json_object_add_uint (counter, "address_length",
5934                                     c4->address_length);
5935           vat_json_object_add_uint (counter, "packets", c4->packets);
5936           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5937         }
5938     }
5939
5940   /* ip6 fib counters */
5941   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5942   vat_json_init_array (msg_array);
5943   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5944     {
5945       msg = vat_json_array_add (msg_array);
5946       vat_json_init_object (msg);
5947       vat_json_object_add_uint (msg, "vrf_id",
5948                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5949       counter_array = vat_json_object_add (msg, "c");
5950       vat_json_init_array (counter_array);
5951       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5952         {
5953           counter = vat_json_array_add (counter_array);
5954           vat_json_init_object (counter);
5955           c6 = &vam->ip6_fib_counters[i][j];
5956           vat_json_object_add_ip6 (counter, "address", c6->address);
5957           vat_json_object_add_uint (counter, "address_length",
5958                                     c6->address_length);
5959           vat_json_object_add_uint (counter, "packets", c6->packets);
5960           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5961         }
5962     }
5963
5964   /* ip4 nbr counters */
5965   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5966   vat_json_init_array (msg_array);
5967   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5968     {
5969       msg = vat_json_array_add (msg_array);
5970       vat_json_init_object (msg);
5971       vat_json_object_add_uint (msg, "sw_if_index", i);
5972       counter_array = vat_json_object_add (msg, "c");
5973       vat_json_init_array (counter_array);
5974       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5975         {
5976           counter = vat_json_array_add (counter_array);
5977           vat_json_init_object (counter);
5978           n4 = &vam->ip4_nbr_counters[i][j];
5979           vat_json_object_add_ip4 (counter, "address", n4->address);
5980           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5981           vat_json_object_add_uint (counter, "packets", n4->packets);
5982           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5983         }
5984     }
5985
5986   /* ip6 nbr counters */
5987   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5988   vat_json_init_array (msg_array);
5989   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5990     {
5991       msg = vat_json_array_add (msg_array);
5992       vat_json_init_object (msg);
5993       vat_json_object_add_uint (msg, "sw_if_index", i);
5994       counter_array = vat_json_object_add (msg, "c");
5995       vat_json_init_array (counter_array);
5996       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5997         {
5998           counter = vat_json_array_add (counter_array);
5999           vat_json_init_object (counter);
6000           n6 = &vam->ip6_nbr_counters[i][j];
6001           vat_json_object_add_ip6 (counter, "address", n6->address);
6002           vat_json_object_add_uint (counter, "packets", n6->packets);
6003           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6004         }
6005     }
6006
6007   vat_json_print (vam->ofp, &node);
6008   vat_json_free (&node);
6009
6010   return 0;
6011 }
6012
6013 /*
6014  * Pass CLI buffers directly in the CLI_INBAND API message,
6015  * instead of an additional shared memory area.
6016  */
6017 static int
6018 exec_inband (vat_main_t * vam)
6019 {
6020   vl_api_cli_inband_t *mp;
6021   unformat_input_t *i = vam->input;
6022   int ret;
6023
6024   if (vec_len (i->buffer) == 0)
6025     return -1;
6026
6027   if (vam->exec_mode == 0 && unformat (i, "mode"))
6028     {
6029       vam->exec_mode = 1;
6030       return 0;
6031     }
6032   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6033     {
6034       vam->exec_mode = 0;
6035       return 0;
6036     }
6037
6038   /*
6039    * In order for the CLI command to work, it
6040    * must be a vector ending in \n, not a C-string ending
6041    * in \n\0.
6042    */
6043   u32 len = vec_len (vam->input->buffer);
6044   M2 (CLI_INBAND, mp, len);
6045   clib_memcpy (mp->cmd, vam->input->buffer, len);
6046   mp->length = htonl (len);
6047
6048   S (mp);
6049   W (ret);
6050   /* json responses may or may not include a useful reply... */
6051   if (vec_len (vam->cmd_reply))
6052     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6053   return ret;
6054 }
6055
6056 int
6057 exec (vat_main_t * vam)
6058 {
6059   return exec_inband (vam);
6060 }
6061
6062 static int
6063 api_create_loopback (vat_main_t * vam)
6064 {
6065   unformat_input_t *i = vam->input;
6066   vl_api_create_loopback_t *mp;
6067   vl_api_create_loopback_instance_t *mp_lbi;
6068   u8 mac_address[6];
6069   u8 mac_set = 0;
6070   u8 is_specified = 0;
6071   u32 user_instance = 0;
6072   int ret;
6073
6074   memset (mac_address, 0, sizeof (mac_address));
6075
6076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6077     {
6078       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6079         mac_set = 1;
6080       if (unformat (i, "instance %d", &user_instance))
6081         is_specified = 1;
6082       else
6083         break;
6084     }
6085
6086   if (is_specified)
6087     {
6088       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6089       mp_lbi->is_specified = is_specified;
6090       if (is_specified)
6091         mp_lbi->user_instance = htonl (user_instance);
6092       if (mac_set)
6093         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6094       S (mp_lbi);
6095     }
6096   else
6097     {
6098       /* Construct the API message */
6099       M (CREATE_LOOPBACK, mp);
6100       if (mac_set)
6101         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6102       S (mp);
6103     }
6104
6105   W (ret);
6106   return ret;
6107 }
6108
6109 static int
6110 api_delete_loopback (vat_main_t * vam)
6111 {
6112   unformat_input_t *i = vam->input;
6113   vl_api_delete_loopback_t *mp;
6114   u32 sw_if_index = ~0;
6115   int ret;
6116
6117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6118     {
6119       if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         ;
6121       else
6122         break;
6123     }
6124
6125   if (sw_if_index == ~0)
6126     {
6127       errmsg ("missing sw_if_index");
6128       return -99;
6129     }
6130
6131   /* Construct the API message */
6132   M (DELETE_LOOPBACK, mp);
6133   mp->sw_if_index = ntohl (sw_if_index);
6134
6135   S (mp);
6136   W (ret);
6137   return ret;
6138 }
6139
6140 static int
6141 api_want_stats (vat_main_t * vam)
6142 {
6143   unformat_input_t *i = vam->input;
6144   vl_api_want_stats_t *mp;
6145   int enable = -1;
6146   int ret;
6147
6148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6149     {
6150       if (unformat (i, "enable"))
6151         enable = 1;
6152       else if (unformat (i, "disable"))
6153         enable = 0;
6154       else
6155         break;
6156     }
6157
6158   if (enable == -1)
6159     {
6160       errmsg ("missing enable|disable");
6161       return -99;
6162     }
6163
6164   M (WANT_STATS, mp);
6165   mp->enable_disable = enable;
6166
6167   S (mp);
6168   W (ret);
6169   return ret;
6170 }
6171
6172 static int
6173 api_want_interface_events (vat_main_t * vam)
6174 {
6175   unformat_input_t *i = vam->input;
6176   vl_api_want_interface_events_t *mp;
6177   int enable = -1;
6178   int ret;
6179
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "enable"))
6183         enable = 1;
6184       else if (unformat (i, "disable"))
6185         enable = 0;
6186       else
6187         break;
6188     }
6189
6190   if (enable == -1)
6191     {
6192       errmsg ("missing enable|disable");
6193       return -99;
6194     }
6195
6196   M (WANT_INTERFACE_EVENTS, mp);
6197   mp->enable_disable = enable;
6198
6199   vam->interface_event_display = enable;
6200
6201   S (mp);
6202   W (ret);
6203   return ret;
6204 }
6205
6206
6207 /* Note: non-static, called once to set up the initial intfc table */
6208 int
6209 api_sw_interface_dump (vat_main_t * vam)
6210 {
6211   vl_api_sw_interface_dump_t *mp;
6212   vl_api_control_ping_t *mp_ping;
6213   hash_pair_t *p;
6214   name_sort_t *nses = 0, *ns;
6215   sw_interface_subif_t *sub = NULL;
6216   int ret;
6217
6218   /* Toss the old name table */
6219   /* *INDENT-OFF* */
6220   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6221   ({
6222     vec_add2 (nses, ns, 1);
6223     ns->name = (u8 *)(p->key);
6224     ns->value = (u32) p->value[0];
6225   }));
6226   /* *INDENT-ON* */
6227
6228   hash_free (vam->sw_if_index_by_interface_name);
6229
6230   vec_foreach (ns, nses) vec_free (ns->name);
6231
6232   vec_free (nses);
6233
6234   vec_foreach (sub, vam->sw_if_subif_table)
6235   {
6236     vec_free (sub->interface_name);
6237   }
6238   vec_free (vam->sw_if_subif_table);
6239
6240   /* recreate the interface name hash table */
6241   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6242
6243   /* Get list of ethernets */
6244   M (SW_INTERFACE_DUMP, mp);
6245   mp->name_filter_valid = 1;
6246   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6247   S (mp);
6248
6249   /* and local / loopback interfaces */
6250   M (SW_INTERFACE_DUMP, mp);
6251   mp->name_filter_valid = 1;
6252   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6253   S (mp);
6254
6255   /* and packet-generator interfaces */
6256   M (SW_INTERFACE_DUMP, mp);
6257   mp->name_filter_valid = 1;
6258   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6259   S (mp);
6260
6261   /* and vxlan-gpe tunnel interfaces */
6262   M (SW_INTERFACE_DUMP, mp);
6263   mp->name_filter_valid = 1;
6264   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6265            sizeof (mp->name_filter) - 1);
6266   S (mp);
6267
6268   /* and vxlan tunnel interfaces */
6269   M (SW_INTERFACE_DUMP, mp);
6270   mp->name_filter_valid = 1;
6271   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6272   S (mp);
6273
6274   /* and geneve tunnel interfaces */
6275   M (SW_INTERFACE_DUMP, mp);
6276   mp->name_filter_valid = 1;
6277   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6278   S (mp);
6279
6280   /* and host (af_packet) interfaces */
6281   M (SW_INTERFACE_DUMP, mp);
6282   mp->name_filter_valid = 1;
6283   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6284   S (mp);
6285
6286   /* and l2tpv3 tunnel interfaces */
6287   M (SW_INTERFACE_DUMP, mp);
6288   mp->name_filter_valid = 1;
6289   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6290            sizeof (mp->name_filter) - 1);
6291   S (mp);
6292
6293   /* and GRE tunnel interfaces */
6294   M (SW_INTERFACE_DUMP, mp);
6295   mp->name_filter_valid = 1;
6296   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6297   S (mp);
6298
6299   /* and LISP-GPE interfaces */
6300   M (SW_INTERFACE_DUMP, mp);
6301   mp->name_filter_valid = 1;
6302   strncpy ((char *) mp->name_filter, "lisp_gpe",
6303            sizeof (mp->name_filter) - 1);
6304   S (mp);
6305
6306   /* and IPSEC tunnel interfaces */
6307   M (SW_INTERFACE_DUMP, mp);
6308   mp->name_filter_valid = 1;
6309   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6310   S (mp);
6311
6312   /* Use a control ping for synchronization */
6313   MPING (CONTROL_PING, mp_ping);
6314   S (mp_ping);
6315
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_sw_interface_set_flags (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_sw_interface_set_flags_t *mp;
6325   u32 sw_if_index;
6326   u8 sw_if_index_set = 0;
6327   u8 admin_up = 0;
6328   int ret;
6329
6330   /* Parse args required to build the message */
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "admin-up"))
6334         admin_up = 1;
6335       else if (unformat (i, "admin-down"))
6336         admin_up = 0;
6337       else
6338         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6339         sw_if_index_set = 1;
6340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6341         sw_if_index_set = 1;
6342       else
6343         break;
6344     }
6345
6346   if (sw_if_index_set == 0)
6347     {
6348       errmsg ("missing interface name or sw_if_index");
6349       return -99;
6350     }
6351
6352   /* Construct the API message */
6353   M (SW_INTERFACE_SET_FLAGS, mp);
6354   mp->sw_if_index = ntohl (sw_if_index);
6355   mp->admin_up_down = admin_up;
6356
6357   /* send it... */
6358   S (mp);
6359
6360   /* Wait for a reply, return the good/bad news... */
6361   W (ret);
6362   return ret;
6363 }
6364
6365 static int
6366 api_sw_interface_set_rx_mode (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_sw_interface_set_rx_mode_t *mp;
6370   u32 sw_if_index;
6371   u8 sw_if_index_set = 0;
6372   int ret;
6373   u8 queue_id_valid = 0;
6374   u32 queue_id;
6375   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6376
6377   /* Parse args required to build the message */
6378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6379     {
6380       if (unformat (i, "queue %d", &queue_id))
6381         queue_id_valid = 1;
6382       else if (unformat (i, "polling"))
6383         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6384       else if (unformat (i, "interrupt"))
6385         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6386       else if (unformat (i, "adaptive"))
6387         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6388       else
6389         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390         sw_if_index_set = 1;
6391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6392         sw_if_index_set = 1;
6393       else
6394         break;
6395     }
6396
6397   if (sw_if_index_set == 0)
6398     {
6399       errmsg ("missing interface name or sw_if_index");
6400       return -99;
6401     }
6402   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6403     {
6404       errmsg ("missing rx-mode");
6405       return -99;
6406     }
6407
6408   /* Construct the API message */
6409   M (SW_INTERFACE_SET_RX_MODE, mp);
6410   mp->sw_if_index = ntohl (sw_if_index);
6411   mp->mode = mode;
6412   mp->queue_id_valid = queue_id_valid;
6413   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6414
6415   /* send it... */
6416   S (mp);
6417
6418   /* Wait for a reply, return the good/bad news... */
6419   W (ret);
6420   return ret;
6421 }
6422
6423 static int
6424 api_sw_interface_clear_stats (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_sw_interface_clear_stats_t *mp;
6428   u32 sw_if_index;
6429   u8 sw_if_index_set = 0;
6430   int ret;
6431
6432   /* Parse args required to build the message */
6433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6434     {
6435       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6436         sw_if_index_set = 1;
6437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6438         sw_if_index_set = 1;
6439       else
6440         break;
6441     }
6442
6443   /* Construct the API message */
6444   M (SW_INTERFACE_CLEAR_STATS, mp);
6445
6446   if (sw_if_index_set == 1)
6447     mp->sw_if_index = ntohl (sw_if_index);
6448   else
6449     mp->sw_if_index = ~0;
6450
6451   /* send it... */
6452   S (mp);
6453
6454   /* Wait for a reply, return the good/bad news... */
6455   W (ret);
6456   return ret;
6457 }
6458
6459 static int
6460 api_sw_interface_add_del_address (vat_main_t * vam)
6461 {
6462   unformat_input_t *i = vam->input;
6463   vl_api_sw_interface_add_del_address_t *mp;
6464   u32 sw_if_index;
6465   u8 sw_if_index_set = 0;
6466   u8 is_add = 1, del_all = 0;
6467   u32 address_length = 0;
6468   u8 v4_address_set = 0;
6469   u8 v6_address_set = 0;
6470   ip4_address_t v4address;
6471   ip6_address_t v6address;
6472   int ret;
6473
6474   /* Parse args required to build the message */
6475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6476     {
6477       if (unformat (i, "del-all"))
6478         del_all = 1;
6479       else if (unformat (i, "del"))
6480         is_add = 0;
6481       else
6482         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6483         sw_if_index_set = 1;
6484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "%U/%d",
6487                          unformat_ip4_address, &v4address, &address_length))
6488         v4_address_set = 1;
6489       else if (unformat (i, "%U/%d",
6490                          unformat_ip6_address, &v6address, &address_length))
6491         v6_address_set = 1;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index_set == 0)
6497     {
6498       errmsg ("missing interface name or sw_if_index");
6499       return -99;
6500     }
6501   if (v4_address_set && v6_address_set)
6502     {
6503       errmsg ("both v4 and v6 addresses set");
6504       return -99;
6505     }
6506   if (!v4_address_set && !v6_address_set && !del_all)
6507     {
6508       errmsg ("no addresses set");
6509       return -99;
6510     }
6511
6512   /* Construct the API message */
6513   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6514
6515   mp->sw_if_index = ntohl (sw_if_index);
6516   mp->is_add = is_add;
6517   mp->del_all = del_all;
6518   if (v6_address_set)
6519     {
6520       mp->is_ipv6 = 1;
6521       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6522     }
6523   else
6524     {
6525       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6526     }
6527   mp->address_length = address_length;
6528
6529   /* send it... */
6530   S (mp);
6531
6532   /* Wait for a reply, return good/bad news  */
6533   W (ret);
6534   return ret;
6535 }
6536
6537 static int
6538 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6539 {
6540   unformat_input_t *i = vam->input;
6541   vl_api_sw_interface_set_mpls_enable_t *mp;
6542   u32 sw_if_index;
6543   u8 sw_if_index_set = 0;
6544   u8 enable = 1;
6545   int ret;
6546
6547   /* Parse args required to build the message */
6548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6549     {
6550       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6551         sw_if_index_set = 1;
6552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6553         sw_if_index_set = 1;
6554       else if (unformat (i, "disable"))
6555         enable = 0;
6556       else if (unformat (i, "dis"))
6557         enable = 0;
6558       else
6559         break;
6560     }
6561
6562   if (sw_if_index_set == 0)
6563     {
6564       errmsg ("missing interface name or sw_if_index");
6565       return -99;
6566     }
6567
6568   /* Construct the API message */
6569   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6570
6571   mp->sw_if_index = ntohl (sw_if_index);
6572   mp->enable = enable;
6573
6574   /* send it... */
6575   S (mp);
6576
6577   /* Wait for a reply... */
6578   W (ret);
6579   return ret;
6580 }
6581
6582 static int
6583 api_sw_interface_set_table (vat_main_t * vam)
6584 {
6585   unformat_input_t *i = vam->input;
6586   vl_api_sw_interface_set_table_t *mp;
6587   u32 sw_if_index, vrf_id = 0;
6588   u8 sw_if_index_set = 0;
6589   u8 is_ipv6 = 0;
6590   int ret;
6591
6592   /* Parse args required to build the message */
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6598         sw_if_index_set = 1;
6599       else if (unformat (i, "vrf %d", &vrf_id))
6600         ;
6601       else if (unformat (i, "ipv6"))
6602         is_ipv6 = 1;
6603       else
6604         break;
6605     }
6606
6607   if (sw_if_index_set == 0)
6608     {
6609       errmsg ("missing interface name or sw_if_index");
6610       return -99;
6611     }
6612
6613   /* Construct the API message */
6614   M (SW_INTERFACE_SET_TABLE, mp);
6615
6616   mp->sw_if_index = ntohl (sw_if_index);
6617   mp->is_ipv6 = is_ipv6;
6618   mp->vrf_id = ntohl (vrf_id);
6619
6620   /* send it... */
6621   S (mp);
6622
6623   /* Wait for a reply... */
6624   W (ret);
6625   return ret;
6626 }
6627
6628 static void vl_api_sw_interface_get_table_reply_t_handler
6629   (vl_api_sw_interface_get_table_reply_t * mp)
6630 {
6631   vat_main_t *vam = &vat_main;
6632
6633   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6634
6635   vam->retval = ntohl (mp->retval);
6636   vam->result_ready = 1;
6637
6638 }
6639
6640 static void vl_api_sw_interface_get_table_reply_t_handler_json
6641   (vl_api_sw_interface_get_table_reply_t * mp)
6642 {
6643   vat_main_t *vam = &vat_main;
6644   vat_json_node_t node;
6645
6646   vat_json_init_object (&node);
6647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6648   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6649
6650   vat_json_print (vam->ofp, &node);
6651   vat_json_free (&node);
6652
6653   vam->retval = ntohl (mp->retval);
6654   vam->result_ready = 1;
6655 }
6656
6657 static int
6658 api_sw_interface_get_table (vat_main_t * vam)
6659 {
6660   unformat_input_t *i = vam->input;
6661   vl_api_sw_interface_get_table_t *mp;
6662   u32 sw_if_index;
6663   u8 sw_if_index_set = 0;
6664   u8 is_ipv6 = 0;
6665   int ret;
6666
6667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6668     {
6669       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6670         sw_if_index_set = 1;
6671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "ipv6"))
6674         is_ipv6 = 1;
6675       else
6676         break;
6677     }
6678
6679   if (sw_if_index_set == 0)
6680     {
6681       errmsg ("missing interface name or sw_if_index");
6682       return -99;
6683     }
6684
6685   M (SW_INTERFACE_GET_TABLE, mp);
6686   mp->sw_if_index = htonl (sw_if_index);
6687   mp->is_ipv6 = is_ipv6;
6688
6689   S (mp);
6690   W (ret);
6691   return ret;
6692 }
6693
6694 static int
6695 api_sw_interface_set_vpath (vat_main_t * vam)
6696 {
6697   unformat_input_t *i = vam->input;
6698   vl_api_sw_interface_set_vpath_t *mp;
6699   u32 sw_if_index = 0;
6700   u8 sw_if_index_set = 0;
6701   u8 is_enable = 0;
6702   int ret;
6703
6704   /* Parse args required to build the message */
6705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6706     {
6707       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6708         sw_if_index_set = 1;
6709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6710         sw_if_index_set = 1;
6711       else if (unformat (i, "enable"))
6712         is_enable = 1;
6713       else if (unformat (i, "disable"))
6714         is_enable = 0;
6715       else
6716         break;
6717     }
6718
6719   if (sw_if_index_set == 0)
6720     {
6721       errmsg ("missing interface name or sw_if_index");
6722       return -99;
6723     }
6724
6725   /* Construct the API message */
6726   M (SW_INTERFACE_SET_VPATH, mp);
6727
6728   mp->sw_if_index = ntohl (sw_if_index);
6729   mp->enable = is_enable;
6730
6731   /* send it... */
6732   S (mp);
6733
6734   /* Wait for a reply... */
6735   W (ret);
6736   return ret;
6737 }
6738
6739 static int
6740 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6741 {
6742   unformat_input_t *i = vam->input;
6743   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6744   u32 sw_if_index = 0;
6745   u8 sw_if_index_set = 0;
6746   u8 is_enable = 1;
6747   u8 is_ipv6 = 0;
6748   int ret;
6749
6750   /* Parse args required to build the message */
6751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6752     {
6753       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6754         sw_if_index_set = 1;
6755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6756         sw_if_index_set = 1;
6757       else if (unformat (i, "enable"))
6758         is_enable = 1;
6759       else if (unformat (i, "disable"))
6760         is_enable = 0;
6761       else if (unformat (i, "ip4"))
6762         is_ipv6 = 0;
6763       else if (unformat (i, "ip6"))
6764         is_ipv6 = 1;
6765       else
6766         break;
6767     }
6768
6769   if (sw_if_index_set == 0)
6770     {
6771       errmsg ("missing interface name or sw_if_index");
6772       return -99;
6773     }
6774
6775   /* Construct the API message */
6776   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6777
6778   mp->sw_if_index = ntohl (sw_if_index);
6779   mp->enable = is_enable;
6780   mp->is_ipv6 = is_ipv6;
6781
6782   /* send it... */
6783   S (mp);
6784
6785   /* Wait for a reply... */
6786   W (ret);
6787   return ret;
6788 }
6789
6790 static int
6791 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6792 {
6793   unformat_input_t *i = vam->input;
6794   vl_api_sw_interface_set_geneve_bypass_t *mp;
6795   u32 sw_if_index = 0;
6796   u8 sw_if_index_set = 0;
6797   u8 is_enable = 1;
6798   u8 is_ipv6 = 0;
6799   int ret;
6800
6801   /* Parse args required to build the message */
6802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6803     {
6804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6805         sw_if_index_set = 1;
6806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6807         sw_if_index_set = 1;
6808       else if (unformat (i, "enable"))
6809         is_enable = 1;
6810       else if (unformat (i, "disable"))
6811         is_enable = 0;
6812       else if (unformat (i, "ip4"))
6813         is_ipv6 = 0;
6814       else if (unformat (i, "ip6"))
6815         is_ipv6 = 1;
6816       else
6817         break;
6818     }
6819
6820   if (sw_if_index_set == 0)
6821     {
6822       errmsg ("missing interface name or sw_if_index");
6823       return -99;
6824     }
6825
6826   /* Construct the API message */
6827   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6828
6829   mp->sw_if_index = ntohl (sw_if_index);
6830   mp->enable = is_enable;
6831   mp->is_ipv6 = is_ipv6;
6832
6833   /* send it... */
6834   S (mp);
6835
6836   /* Wait for a reply... */
6837   W (ret);
6838   return ret;
6839 }
6840
6841 static int
6842 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6843 {
6844   unformat_input_t *i = vam->input;
6845   vl_api_sw_interface_set_l2_xconnect_t *mp;
6846   u32 rx_sw_if_index;
6847   u8 rx_sw_if_index_set = 0;
6848   u32 tx_sw_if_index;
6849   u8 tx_sw_if_index_set = 0;
6850   u8 enable = 1;
6851   int ret;
6852
6853   /* Parse args required to build the message */
6854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6855     {
6856       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6857         rx_sw_if_index_set = 1;
6858       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6859         tx_sw_if_index_set = 1;
6860       else if (unformat (i, "rx"))
6861         {
6862           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6863             {
6864               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6865                             &rx_sw_if_index))
6866                 rx_sw_if_index_set = 1;
6867             }
6868           else
6869             break;
6870         }
6871       else if (unformat (i, "tx"))
6872         {
6873           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6874             {
6875               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6876                             &tx_sw_if_index))
6877                 tx_sw_if_index_set = 1;
6878             }
6879           else
6880             break;
6881         }
6882       else if (unformat (i, "enable"))
6883         enable = 1;
6884       else if (unformat (i, "disable"))
6885         enable = 0;
6886       else
6887         break;
6888     }
6889
6890   if (rx_sw_if_index_set == 0)
6891     {
6892       errmsg ("missing rx interface name or rx_sw_if_index");
6893       return -99;
6894     }
6895
6896   if (enable && (tx_sw_if_index_set == 0))
6897     {
6898       errmsg ("missing tx interface name or tx_sw_if_index");
6899       return -99;
6900     }
6901
6902   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6903
6904   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6905   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6906   mp->enable = enable;
6907
6908   S (mp);
6909   W (ret);
6910   return ret;
6911 }
6912
6913 static int
6914 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_sw_interface_set_l2_bridge_t *mp;
6918   u32 rx_sw_if_index;
6919   u8 rx_sw_if_index_set = 0;
6920   u32 bd_id;
6921   u8 bd_id_set = 0;
6922   u8 bvi = 0;
6923   u32 shg = 0;
6924   u8 enable = 1;
6925   int ret;
6926
6927   /* Parse args required to build the message */
6928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6929     {
6930       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6931         rx_sw_if_index_set = 1;
6932       else if (unformat (i, "bd_id %d", &bd_id))
6933         bd_id_set = 1;
6934       else
6935         if (unformat
6936             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6937         rx_sw_if_index_set = 1;
6938       else if (unformat (i, "shg %d", &shg))
6939         ;
6940       else if (unformat (i, "bvi"))
6941         bvi = 1;
6942       else if (unformat (i, "enable"))
6943         enable = 1;
6944       else if (unformat (i, "disable"))
6945         enable = 0;
6946       else
6947         break;
6948     }
6949
6950   if (rx_sw_if_index_set == 0)
6951     {
6952       errmsg ("missing rx interface name or sw_if_index");
6953       return -99;
6954     }
6955
6956   if (enable && (bd_id_set == 0))
6957     {
6958       errmsg ("missing bridge domain");
6959       return -99;
6960     }
6961
6962   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6963
6964   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6965   mp->bd_id = ntohl (bd_id);
6966   mp->shg = (u8) shg;
6967   mp->bvi = bvi;
6968   mp->enable = enable;
6969
6970   S (mp);
6971   W (ret);
6972   return ret;
6973 }
6974
6975 static int
6976 api_bridge_domain_dump (vat_main_t * vam)
6977 {
6978   unformat_input_t *i = vam->input;
6979   vl_api_bridge_domain_dump_t *mp;
6980   vl_api_control_ping_t *mp_ping;
6981   u32 bd_id = ~0;
6982   int ret;
6983
6984   /* Parse args required to build the message */
6985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6986     {
6987       if (unformat (i, "bd_id %d", &bd_id))
6988         ;
6989       else
6990         break;
6991     }
6992
6993   M (BRIDGE_DOMAIN_DUMP, mp);
6994   mp->bd_id = ntohl (bd_id);
6995   S (mp);
6996
6997   /* Use a control ping for synchronization */
6998   MPING (CONTROL_PING, mp_ping);
6999   S (mp_ping);
7000
7001   W (ret);
7002   return ret;
7003 }
7004
7005 static int
7006 api_bridge_domain_add_del (vat_main_t * vam)
7007 {
7008   unformat_input_t *i = vam->input;
7009   vl_api_bridge_domain_add_del_t *mp;
7010   u32 bd_id = ~0;
7011   u8 is_add = 1;
7012   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7013   u8 *bd_tag = NULL;
7014   u32 mac_age = 0;
7015   int ret;
7016
7017   /* Parse args required to build the message */
7018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7019     {
7020       if (unformat (i, "bd_id %d", &bd_id))
7021         ;
7022       else if (unformat (i, "flood %d", &flood))
7023         ;
7024       else if (unformat (i, "uu-flood %d", &uu_flood))
7025         ;
7026       else if (unformat (i, "forward %d", &forward))
7027         ;
7028       else if (unformat (i, "learn %d", &learn))
7029         ;
7030       else if (unformat (i, "arp-term %d", &arp_term))
7031         ;
7032       else if (unformat (i, "mac-age %d", &mac_age))
7033         ;
7034       else if (unformat (i, "bd-tag %s", &bd_tag))
7035         ;
7036       else if (unformat (i, "del"))
7037         {
7038           is_add = 0;
7039           flood = uu_flood = forward = learn = 0;
7040         }
7041       else
7042         break;
7043     }
7044
7045   if (bd_id == ~0)
7046     {
7047       errmsg ("missing bridge domain");
7048       ret = -99;
7049       goto done;
7050     }
7051
7052   if (mac_age > 255)
7053     {
7054       errmsg ("mac age must be less than 256 ");
7055       ret = -99;
7056       goto done;
7057     }
7058
7059   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7060     {
7061       errmsg ("bd-tag cannot be longer than 63");
7062       ret = -99;
7063       goto done;
7064     }
7065
7066   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7067
7068   mp->bd_id = ntohl (bd_id);
7069   mp->flood = flood;
7070   mp->uu_flood = uu_flood;
7071   mp->forward = forward;
7072   mp->learn = learn;
7073   mp->arp_term = arp_term;
7074   mp->is_add = is_add;
7075   mp->mac_age = (u8) mac_age;
7076   if (bd_tag)
7077     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7078
7079   S (mp);
7080   W (ret);
7081
7082 done:
7083   vec_free (bd_tag);
7084   return ret;
7085 }
7086
7087 static int
7088 api_l2fib_flush_bd (vat_main_t * vam)
7089 {
7090   unformat_input_t *i = vam->input;
7091   vl_api_l2fib_flush_bd_t *mp;
7092   u32 bd_id = ~0;
7093   int ret;
7094
7095   /* Parse args required to build the message */
7096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7097     {
7098       if (unformat (i, "bd_id %d", &bd_id));
7099       else
7100         break;
7101     }
7102
7103   if (bd_id == ~0)
7104     {
7105       errmsg ("missing bridge domain");
7106       return -99;
7107     }
7108
7109   M (L2FIB_FLUSH_BD, mp);
7110
7111   mp->bd_id = htonl (bd_id);
7112
7113   S (mp);
7114   W (ret);
7115   return ret;
7116 }
7117
7118 static int
7119 api_l2fib_flush_int (vat_main_t * vam)
7120 {
7121   unformat_input_t *i = vam->input;
7122   vl_api_l2fib_flush_int_t *mp;
7123   u32 sw_if_index = ~0;
7124   int ret;
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "sw_if_index %d", &sw_if_index));
7130       else
7131         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7132       else
7133         break;
7134     }
7135
7136   if (sw_if_index == ~0)
7137     {
7138       errmsg ("missing interface name or sw_if_index");
7139       return -99;
7140     }
7141
7142   M (L2FIB_FLUSH_INT, mp);
7143
7144   mp->sw_if_index = ntohl (sw_if_index);
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2fib_add_del (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2fib_add_del_t *mp;
7156   f64 timeout;
7157   u8 mac[6] = { 0 };
7158   u8 mac_set = 0;
7159   u32 bd_id;
7160   u8 bd_id_set = 0;
7161   u32 sw_if_index = ~0;
7162   u8 sw_if_index_set = 0;
7163   u8 is_add = 1;
7164   u8 static_mac = 0;
7165   u8 filter_mac = 0;
7166   u8 bvi_mac = 0;
7167   int count = 1;
7168   f64 before = 0;
7169   int j;
7170
7171   /* Parse args required to build the message */
7172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7173     {
7174       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7175         mac_set = 1;
7176       else if (unformat (i, "bd_id %d", &bd_id))
7177         bd_id_set = 1;
7178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7179         sw_if_index_set = 1;
7180       else if (unformat (i, "sw_if"))
7181         {
7182           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7183             {
7184               if (unformat
7185                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7186                 sw_if_index_set = 1;
7187             }
7188           else
7189             break;
7190         }
7191       else if (unformat (i, "static"))
7192         static_mac = 1;
7193       else if (unformat (i, "filter"))
7194         {
7195           filter_mac = 1;
7196           static_mac = 1;
7197         }
7198       else if (unformat (i, "bvi"))
7199         {
7200           bvi_mac = 1;
7201           static_mac = 1;
7202         }
7203       else if (unformat (i, "del"))
7204         is_add = 0;
7205       else if (unformat (i, "count %d", &count))
7206         ;
7207       else
7208         break;
7209     }
7210
7211   if (mac_set == 0)
7212     {
7213       errmsg ("missing mac address");
7214       return -99;
7215     }
7216
7217   if (bd_id_set == 0)
7218     {
7219       errmsg ("missing bridge domain");
7220       return -99;
7221     }
7222
7223   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7224     {
7225       errmsg ("missing interface name or sw_if_index");
7226       return -99;
7227     }
7228
7229   if (count > 1)
7230     {
7231       /* Turn on async mode */
7232       vam->async_mode = 1;
7233       vam->async_errors = 0;
7234       before = vat_time_now (vam);
7235     }
7236
7237   for (j = 0; j < count; j++)
7238     {
7239       M (L2FIB_ADD_DEL, mp);
7240
7241       clib_memcpy (mp->mac, mac, 6);
7242       mp->bd_id = ntohl (bd_id);
7243       mp->is_add = is_add;
7244
7245       if (is_add)
7246         {
7247           mp->sw_if_index = ntohl (sw_if_index);
7248           mp->static_mac = static_mac;
7249           mp->filter_mac = filter_mac;
7250           mp->bvi_mac = bvi_mac;
7251         }
7252       increment_mac_address (mac);
7253       /* send it... */
7254       S (mp);
7255     }
7256
7257   if (count > 1)
7258     {
7259       vl_api_control_ping_t *mp_ping;
7260       f64 after;
7261
7262       /* Shut off async mode */
7263       vam->async_mode = 0;
7264
7265       MPING (CONTROL_PING, mp_ping);
7266       S (mp_ping);
7267
7268       timeout = vat_time_now (vam) + 1.0;
7269       while (vat_time_now (vam) < timeout)
7270         if (vam->result_ready == 1)
7271           goto out;
7272       vam->retval = -99;
7273
7274     out:
7275       if (vam->retval == -99)
7276         errmsg ("timeout");
7277
7278       if (vam->async_errors > 0)
7279         {
7280           errmsg ("%d asynchronous errors", vam->async_errors);
7281           vam->retval = -98;
7282         }
7283       vam->async_errors = 0;
7284       after = vat_time_now (vam);
7285
7286       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7287              count, after - before, count / (after - before));
7288     }
7289   else
7290     {
7291       int ret;
7292
7293       /* Wait for a reply... */
7294       W (ret);
7295       return ret;
7296     }
7297   /* Return the good/bad news */
7298   return (vam->retval);
7299 }
7300
7301 static int
7302 api_bridge_domain_set_mac_age (vat_main_t * vam)
7303 {
7304   unformat_input_t *i = vam->input;
7305   vl_api_bridge_domain_set_mac_age_t *mp;
7306   u32 bd_id = ~0;
7307   u32 mac_age = 0;
7308   int ret;
7309
7310   /* Parse args required to build the message */
7311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7312     {
7313       if (unformat (i, "bd_id %d", &bd_id));
7314       else if (unformat (i, "mac-age %d", &mac_age));
7315       else
7316         break;
7317     }
7318
7319   if (bd_id == ~0)
7320     {
7321       errmsg ("missing bridge domain");
7322       return -99;
7323     }
7324
7325   if (mac_age > 255)
7326     {
7327       errmsg ("mac age must be less than 256 ");
7328       return -99;
7329     }
7330
7331   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7332
7333   mp->bd_id = htonl (bd_id);
7334   mp->mac_age = (u8) mac_age;
7335
7336   S (mp);
7337   W (ret);
7338   return ret;
7339 }
7340
7341 static int
7342 api_l2_flags (vat_main_t * vam)
7343 {
7344   unformat_input_t *i = vam->input;
7345   vl_api_l2_flags_t *mp;
7346   u32 sw_if_index;
7347   u32 flags = 0;
7348   u8 sw_if_index_set = 0;
7349   u8 is_set = 0;
7350   int ret;
7351
7352   /* Parse args required to build the message */
7353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7354     {
7355       if (unformat (i, "sw_if_index %d", &sw_if_index))
7356         sw_if_index_set = 1;
7357       else if (unformat (i, "sw_if"))
7358         {
7359           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7360             {
7361               if (unformat
7362                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7363                 sw_if_index_set = 1;
7364             }
7365           else
7366             break;
7367         }
7368       else if (unformat (i, "learn"))
7369         flags |= L2_LEARN;
7370       else if (unformat (i, "forward"))
7371         flags |= L2_FWD;
7372       else if (unformat (i, "flood"))
7373         flags |= L2_FLOOD;
7374       else if (unformat (i, "uu-flood"))
7375         flags |= L2_UU_FLOOD;
7376       else if (unformat (i, "arp-term"))
7377         flags |= L2_ARP_TERM;
7378       else if (unformat (i, "off"))
7379         is_set = 0;
7380       else if (unformat (i, "disable"))
7381         is_set = 0;
7382       else
7383         break;
7384     }
7385
7386   if (sw_if_index_set == 0)
7387     {
7388       errmsg ("missing interface name or sw_if_index");
7389       return -99;
7390     }
7391
7392   M (L2_FLAGS, mp);
7393
7394   mp->sw_if_index = ntohl (sw_if_index);
7395   mp->feature_bitmap = ntohl (flags);
7396   mp->is_set = is_set;
7397
7398   S (mp);
7399   W (ret);
7400   return ret;
7401 }
7402
7403 static int
7404 api_bridge_flags (vat_main_t * vam)
7405 {
7406   unformat_input_t *i = vam->input;
7407   vl_api_bridge_flags_t *mp;
7408   u32 bd_id;
7409   u8 bd_id_set = 0;
7410   u8 is_set = 1;
7411   u32 flags = 0;
7412   int ret;
7413
7414   /* Parse args required to build the message */
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "bd_id %d", &bd_id))
7418         bd_id_set = 1;
7419       else if (unformat (i, "learn"))
7420         flags |= L2_LEARN;
7421       else if (unformat (i, "forward"))
7422         flags |= L2_FWD;
7423       else if (unformat (i, "flood"))
7424         flags |= L2_FLOOD;
7425       else if (unformat (i, "uu-flood"))
7426         flags |= L2_UU_FLOOD;
7427       else if (unformat (i, "arp-term"))
7428         flags |= L2_ARP_TERM;
7429       else if (unformat (i, "off"))
7430         is_set = 0;
7431       else if (unformat (i, "disable"))
7432         is_set = 0;
7433       else
7434         break;
7435     }
7436
7437   if (bd_id_set == 0)
7438     {
7439       errmsg ("missing bridge domain");
7440       return -99;
7441     }
7442
7443   M (BRIDGE_FLAGS, mp);
7444
7445   mp->bd_id = ntohl (bd_id);
7446   mp->feature_bitmap = ntohl (flags);
7447   mp->is_set = is_set;
7448
7449   S (mp);
7450   W (ret);
7451   return ret;
7452 }
7453
7454 static int
7455 api_bd_ip_mac_add_del (vat_main_t * vam)
7456 {
7457   unformat_input_t *i = vam->input;
7458   vl_api_bd_ip_mac_add_del_t *mp;
7459   u32 bd_id;
7460   u8 is_ipv6 = 0;
7461   u8 is_add = 1;
7462   u8 bd_id_set = 0;
7463   u8 ip_set = 0;
7464   u8 mac_set = 0;
7465   ip4_address_t v4addr;
7466   ip6_address_t v6addr;
7467   u8 macaddr[6];
7468   int ret;
7469
7470
7471   /* Parse args required to build the message */
7472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7473     {
7474       if (unformat (i, "bd_id %d", &bd_id))
7475         {
7476           bd_id_set++;
7477         }
7478       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7479         {
7480           ip_set++;
7481         }
7482       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7483         {
7484           ip_set++;
7485           is_ipv6++;
7486         }
7487       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7488         {
7489           mac_set++;
7490         }
7491       else if (unformat (i, "del"))
7492         is_add = 0;
7493       else
7494         break;
7495     }
7496
7497   if (bd_id_set == 0)
7498     {
7499       errmsg ("missing bridge domain");
7500       return -99;
7501     }
7502   else if (ip_set == 0)
7503     {
7504       errmsg ("missing IP address");
7505       return -99;
7506     }
7507   else if (mac_set == 0)
7508     {
7509       errmsg ("missing MAC address");
7510       return -99;
7511     }
7512
7513   M (BD_IP_MAC_ADD_DEL, mp);
7514
7515   mp->bd_id = ntohl (bd_id);
7516   mp->is_ipv6 = is_ipv6;
7517   mp->is_add = is_add;
7518   if (is_ipv6)
7519     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7520   else
7521     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7522   clib_memcpy (mp->mac_address, macaddr, 6);
7523   S (mp);
7524   W (ret);
7525   return ret;
7526 }
7527
7528 static int
7529 api_tap_connect (vat_main_t * vam)
7530 {
7531   unformat_input_t *i = vam->input;
7532   vl_api_tap_connect_t *mp;
7533   u8 mac_address[6];
7534   u8 random_mac = 1;
7535   u8 name_set = 0;
7536   u8 *tap_name;
7537   u8 *tag = 0;
7538   ip4_address_t ip4_address;
7539   u32 ip4_mask_width;
7540   int ip4_address_set = 0;
7541   ip6_address_t ip6_address;
7542   u32 ip6_mask_width;
7543   int ip6_address_set = 0;
7544   int ret;
7545
7546   memset (mac_address, 0, sizeof (mac_address));
7547
7548   /* Parse args required to build the message */
7549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550     {
7551       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7552         {
7553           random_mac = 0;
7554         }
7555       else if (unformat (i, "random-mac"))
7556         random_mac = 1;
7557       else if (unformat (i, "tapname %s", &tap_name))
7558         name_set = 1;
7559       else if (unformat (i, "tag %s", &tag))
7560         ;
7561       else if (unformat (i, "address %U/%d",
7562                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7563         ip4_address_set = 1;
7564       else if (unformat (i, "address %U/%d",
7565                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7566         ip6_address_set = 1;
7567       else
7568         break;
7569     }
7570
7571   if (name_set == 0)
7572     {
7573       errmsg ("missing tap name");
7574       return -99;
7575     }
7576   if (vec_len (tap_name) > 63)
7577     {
7578       errmsg ("tap name too long");
7579       return -99;
7580     }
7581   vec_add1 (tap_name, 0);
7582
7583   if (vec_len (tag) > 63)
7584     {
7585       errmsg ("tag too long");
7586       return -99;
7587     }
7588
7589   /* Construct the API message */
7590   M (TAP_CONNECT, mp);
7591
7592   mp->use_random_mac = random_mac;
7593   clib_memcpy (mp->mac_address, mac_address, 6);
7594   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7595   if (tag)
7596     clib_memcpy (mp->tag, tag, vec_len (tag));
7597
7598   if (ip4_address_set)
7599     {
7600       mp->ip4_address_set = 1;
7601       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7602       mp->ip4_mask_width = ip4_mask_width;
7603     }
7604   if (ip6_address_set)
7605     {
7606       mp->ip6_address_set = 1;
7607       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7608       mp->ip6_mask_width = ip6_mask_width;
7609     }
7610
7611   vec_free (tap_name);
7612   vec_free (tag);
7613
7614   /* send it... */
7615   S (mp);
7616
7617   /* Wait for a reply... */
7618   W (ret);
7619   return ret;
7620 }
7621
7622 static int
7623 api_tap_modify (vat_main_t * vam)
7624 {
7625   unformat_input_t *i = vam->input;
7626   vl_api_tap_modify_t *mp;
7627   u8 mac_address[6];
7628   u8 random_mac = 1;
7629   u8 name_set = 0;
7630   u8 *tap_name;
7631   u32 sw_if_index = ~0;
7632   u8 sw_if_index_set = 0;
7633   int ret;
7634
7635   memset (mac_address, 0, sizeof (mac_address));
7636
7637   /* Parse args required to build the message */
7638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7639     {
7640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7641         sw_if_index_set = 1;
7642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7643         sw_if_index_set = 1;
7644       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7645         {
7646           random_mac = 0;
7647         }
7648       else if (unformat (i, "random-mac"))
7649         random_mac = 1;
7650       else if (unformat (i, "tapname %s", &tap_name))
7651         name_set = 1;
7652       else
7653         break;
7654     }
7655
7656   if (sw_if_index_set == 0)
7657     {
7658       errmsg ("missing vpp interface name");
7659       return -99;
7660     }
7661   if (name_set == 0)
7662     {
7663       errmsg ("missing tap name");
7664       return -99;
7665     }
7666   if (vec_len (tap_name) > 63)
7667     {
7668       errmsg ("tap name too long");
7669     }
7670   vec_add1 (tap_name, 0);
7671
7672   /* Construct the API message */
7673   M (TAP_MODIFY, mp);
7674
7675   mp->use_random_mac = random_mac;
7676   mp->sw_if_index = ntohl (sw_if_index);
7677   clib_memcpy (mp->mac_address, mac_address, 6);
7678   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7679   vec_free (tap_name);
7680
7681   /* send it... */
7682   S (mp);
7683
7684   /* Wait for a reply... */
7685   W (ret);
7686   return ret;
7687 }
7688
7689 static int
7690 api_tap_delete (vat_main_t * vam)
7691 {
7692   unformat_input_t *i = vam->input;
7693   vl_api_tap_delete_t *mp;
7694   u32 sw_if_index = ~0;
7695   u8 sw_if_index_set = 0;
7696   int ret;
7697
7698   /* Parse args required to build the message */
7699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7700     {
7701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7702         sw_if_index_set = 1;
7703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7704         sw_if_index_set = 1;
7705       else
7706         break;
7707     }
7708
7709   if (sw_if_index_set == 0)
7710     {
7711       errmsg ("missing vpp interface name");
7712       return -99;
7713     }
7714
7715   /* Construct the API message */
7716   M (TAP_DELETE, mp);
7717
7718   mp->sw_if_index = ntohl (sw_if_index);
7719
7720   /* send it... */
7721   S (mp);
7722
7723   /* Wait for a reply... */
7724   W (ret);
7725   return ret;
7726 }
7727
7728 static int
7729 api_ip_table_add_del (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_ip_table_add_del_t *mp;
7733   u32 table_id = ~0;
7734   u8 is_ipv6 = 0;
7735   u8 is_add = 1;
7736   int ret = 0;
7737
7738   /* Parse args required to build the message */
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "ipv6"))
7742         is_ipv6 = 1;
7743       else if (unformat (i, "del"))
7744         is_add = 0;
7745       else if (unformat (i, "add"))
7746         is_add = 1;
7747       else if (unformat (i, "table %d", &table_id))
7748         ;
7749       else
7750         {
7751           clib_warning ("parse error '%U'", format_unformat_error, i);
7752           return -99;
7753         }
7754     }
7755
7756   if (~0 == table_id)
7757     {
7758       errmsg ("missing table-ID");
7759       return -99;
7760     }
7761
7762   /* Construct the API message */
7763   M (IP_TABLE_ADD_DEL, mp);
7764
7765   mp->table_id = ntohl (table_id);
7766   mp->is_ipv6 = is_ipv6;
7767   mp->is_add = is_add;
7768
7769   /* send it... */
7770   S (mp);
7771
7772   /* Wait for a reply... */
7773   W (ret);
7774
7775   return ret;
7776 }
7777
7778 static int
7779 api_ip_add_del_route (vat_main_t * vam)
7780 {
7781   unformat_input_t *i = vam->input;
7782   vl_api_ip_add_del_route_t *mp;
7783   u32 sw_if_index = ~0, vrf_id = 0;
7784   u8 is_ipv6 = 0;
7785   u8 is_local = 0, is_drop = 0;
7786   u8 is_unreach = 0, is_prohibit = 0;
7787   u8 create_vrf_if_needed = 0;
7788   u8 is_add = 1;
7789   u32 next_hop_weight = 1;
7790   u8 is_multipath = 0;
7791   u8 address_set = 0;
7792   u8 address_length_set = 0;
7793   u32 next_hop_table_id = 0;
7794   u32 resolve_attempts = 0;
7795   u32 dst_address_length = 0;
7796   u8 next_hop_set = 0;
7797   ip4_address_t v4_dst_address, v4_next_hop_address;
7798   ip6_address_t v6_dst_address, v6_next_hop_address;
7799   int count = 1;
7800   int j;
7801   f64 before = 0;
7802   u32 random_add_del = 0;
7803   u32 *random_vector = 0;
7804   uword *random_hash;
7805   u32 random_seed = 0xdeaddabe;
7806   u32 classify_table_index = ~0;
7807   u8 is_classify = 0;
7808   u8 resolve_host = 0, resolve_attached = 0;
7809   mpls_label_t *next_hop_out_label_stack = NULL;
7810   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7811   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7812
7813   /* Parse args required to build the message */
7814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7817         ;
7818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7819         ;
7820       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7821         {
7822           address_set = 1;
7823           is_ipv6 = 0;
7824         }
7825       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7826         {
7827           address_set = 1;
7828           is_ipv6 = 1;
7829         }
7830       else if (unformat (i, "/%d", &dst_address_length))
7831         {
7832           address_length_set = 1;
7833         }
7834
7835       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7836                                          &v4_next_hop_address))
7837         {
7838           next_hop_set = 1;
7839         }
7840       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7841                                          &v6_next_hop_address))
7842         {
7843           next_hop_set = 1;
7844         }
7845       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7846         ;
7847       else if (unformat (i, "weight %d", &next_hop_weight))
7848         ;
7849       else if (unformat (i, "drop"))
7850         {
7851           is_drop = 1;
7852         }
7853       else if (unformat (i, "null-send-unreach"))
7854         {
7855           is_unreach = 1;
7856         }
7857       else if (unformat (i, "null-send-prohibit"))
7858         {
7859           is_prohibit = 1;
7860         }
7861       else if (unformat (i, "local"))
7862         {
7863           is_local = 1;
7864         }
7865       else if (unformat (i, "classify %d", &classify_table_index))
7866         {
7867           is_classify = 1;
7868         }
7869       else if (unformat (i, "del"))
7870         is_add = 0;
7871       else if (unformat (i, "add"))
7872         is_add = 1;
7873       else if (unformat (i, "resolve-via-host"))
7874         resolve_host = 1;
7875       else if (unformat (i, "resolve-via-attached"))
7876         resolve_attached = 1;
7877       else if (unformat (i, "multipath"))
7878         is_multipath = 1;
7879       else if (unformat (i, "vrf %d", &vrf_id))
7880         ;
7881       else if (unformat (i, "create-vrf"))
7882         create_vrf_if_needed = 1;
7883       else if (unformat (i, "count %d", &count))
7884         ;
7885       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7886         ;
7887       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7888         ;
7889       else if (unformat (i, "out-label %d", &next_hop_out_label))
7890         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7891       else if (unformat (i, "via-label %d", &next_hop_via_label))
7892         ;
7893       else if (unformat (i, "random"))
7894         random_add_del = 1;
7895       else if (unformat (i, "seed %d", &random_seed))
7896         ;
7897       else
7898         {
7899           clib_warning ("parse error '%U'", format_unformat_error, i);
7900           return -99;
7901         }
7902     }
7903
7904   if (!next_hop_set && !is_drop && !is_local &&
7905       !is_classify && !is_unreach && !is_prohibit &&
7906       MPLS_LABEL_INVALID == next_hop_via_label)
7907     {
7908       errmsg
7909         ("next hop / local / drop / unreach / prohibit / classify not set");
7910       return -99;
7911     }
7912
7913   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7914     {
7915       errmsg ("next hop and next-hop via label set");
7916       return -99;
7917     }
7918   if (address_set == 0)
7919     {
7920       errmsg ("missing addresses");
7921       return -99;
7922     }
7923
7924   if (address_length_set == 0)
7925     {
7926       errmsg ("missing address length");
7927       return -99;
7928     }
7929
7930   /* Generate a pile of unique, random routes */
7931   if (random_add_del)
7932     {
7933       u32 this_random_address;
7934       random_hash = hash_create (count, sizeof (uword));
7935
7936       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7937       for (j = 0; j <= count; j++)
7938         {
7939           do
7940             {
7941               this_random_address = random_u32 (&random_seed);
7942               this_random_address =
7943                 clib_host_to_net_u32 (this_random_address);
7944             }
7945           while (hash_get (random_hash, this_random_address));
7946           vec_add1 (random_vector, this_random_address);
7947           hash_set (random_hash, this_random_address, 1);
7948         }
7949       hash_free (random_hash);
7950       v4_dst_address.as_u32 = random_vector[0];
7951     }
7952
7953   if (count > 1)
7954     {
7955       /* Turn on async mode */
7956       vam->async_mode = 1;
7957       vam->async_errors = 0;
7958       before = vat_time_now (vam);
7959     }
7960
7961   for (j = 0; j < count; j++)
7962     {
7963       /* Construct the API message */
7964       M2 (IP_ADD_DEL_ROUTE, mp,
7965           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7966
7967       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7968       mp->table_id = ntohl (vrf_id);
7969       mp->create_vrf_if_needed = create_vrf_if_needed;
7970
7971       mp->is_add = is_add;
7972       mp->is_drop = is_drop;
7973       mp->is_unreach = is_unreach;
7974       mp->is_prohibit = is_prohibit;
7975       mp->is_ipv6 = is_ipv6;
7976       mp->is_local = is_local;
7977       mp->is_classify = is_classify;
7978       mp->is_multipath = is_multipath;
7979       mp->is_resolve_host = resolve_host;
7980       mp->is_resolve_attached = resolve_attached;
7981       mp->next_hop_weight = next_hop_weight;
7982       mp->dst_address_length = dst_address_length;
7983       mp->next_hop_table_id = ntohl (next_hop_table_id);
7984       mp->classify_table_index = ntohl (classify_table_index);
7985       mp->next_hop_via_label = ntohl (next_hop_via_label);
7986       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7987       if (0 != mp->next_hop_n_out_labels)
7988         {
7989           memcpy (mp->next_hop_out_label_stack,
7990                   next_hop_out_label_stack,
7991                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7992           vec_free (next_hop_out_label_stack);
7993         }
7994
7995       if (is_ipv6)
7996         {
7997           clib_memcpy (mp->dst_address, &v6_dst_address,
7998                        sizeof (v6_dst_address));
7999           if (next_hop_set)
8000             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8001                          sizeof (v6_next_hop_address));
8002           increment_v6_address (&v6_dst_address);
8003         }
8004       else
8005         {
8006           clib_memcpy (mp->dst_address, &v4_dst_address,
8007                        sizeof (v4_dst_address));
8008           if (next_hop_set)
8009             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8010                          sizeof (v4_next_hop_address));
8011           if (random_add_del)
8012             v4_dst_address.as_u32 = random_vector[j + 1];
8013           else
8014             increment_v4_address (&v4_dst_address);
8015         }
8016       /* send it... */
8017       S (mp);
8018       /* If we receive SIGTERM, stop now... */
8019       if (vam->do_exit)
8020         break;
8021     }
8022
8023   /* When testing multiple add/del ops, use a control-ping to sync */
8024   if (count > 1)
8025     {
8026       vl_api_control_ping_t *mp_ping;
8027       f64 after;
8028       f64 timeout;
8029
8030       /* Shut off async mode */
8031       vam->async_mode = 0;
8032
8033       MPING (CONTROL_PING, mp_ping);
8034       S (mp_ping);
8035
8036       timeout = vat_time_now (vam) + 1.0;
8037       while (vat_time_now (vam) < timeout)
8038         if (vam->result_ready == 1)
8039           goto out;
8040       vam->retval = -99;
8041
8042     out:
8043       if (vam->retval == -99)
8044         errmsg ("timeout");
8045
8046       if (vam->async_errors > 0)
8047         {
8048           errmsg ("%d asynchronous errors", vam->async_errors);
8049           vam->retval = -98;
8050         }
8051       vam->async_errors = 0;
8052       after = vat_time_now (vam);
8053
8054       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8055       if (j > 0)
8056         count = j;
8057
8058       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8059              count, after - before, count / (after - before));
8060     }
8061   else
8062     {
8063       int ret;
8064
8065       /* Wait for a reply... */
8066       W (ret);
8067       return ret;
8068     }
8069
8070   /* Return the good/bad news */
8071   return (vam->retval);
8072 }
8073
8074 static int
8075 api_ip_mroute_add_del (vat_main_t * vam)
8076 {
8077   unformat_input_t *i = vam->input;
8078   vl_api_ip_mroute_add_del_t *mp;
8079   u32 sw_if_index = ~0, vrf_id = 0;
8080   u8 is_ipv6 = 0;
8081   u8 is_local = 0;
8082   u8 create_vrf_if_needed = 0;
8083   u8 is_add = 1;
8084   u8 address_set = 0;
8085   u32 grp_address_length = 0;
8086   ip4_address_t v4_grp_address, v4_src_address;
8087   ip6_address_t v6_grp_address, v6_src_address;
8088   mfib_itf_flags_t iflags = 0;
8089   mfib_entry_flags_t eflags = 0;
8090   int ret;
8091
8092   /* Parse args required to build the message */
8093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8094     {
8095       if (unformat (i, "sw_if_index %d", &sw_if_index))
8096         ;
8097       else if (unformat (i, "%U %U",
8098                          unformat_ip4_address, &v4_src_address,
8099                          unformat_ip4_address, &v4_grp_address))
8100         {
8101           grp_address_length = 64;
8102           address_set = 1;
8103           is_ipv6 = 0;
8104         }
8105       else if (unformat (i, "%U %U",
8106                          unformat_ip6_address, &v6_src_address,
8107                          unformat_ip6_address, &v6_grp_address))
8108         {
8109           grp_address_length = 256;
8110           address_set = 1;
8111           is_ipv6 = 1;
8112         }
8113       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8114         {
8115           memset (&v4_src_address, 0, sizeof (v4_src_address));
8116           grp_address_length = 32;
8117           address_set = 1;
8118           is_ipv6 = 0;
8119         }
8120       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8121         {
8122           memset (&v6_src_address, 0, sizeof (v6_src_address));
8123           grp_address_length = 128;
8124           address_set = 1;
8125           is_ipv6 = 1;
8126         }
8127       else if (unformat (i, "/%d", &grp_address_length))
8128         ;
8129       else if (unformat (i, "local"))
8130         {
8131           is_local = 1;
8132         }
8133       else if (unformat (i, "del"))
8134         is_add = 0;
8135       else if (unformat (i, "add"))
8136         is_add = 1;
8137       else if (unformat (i, "vrf %d", &vrf_id))
8138         ;
8139       else if (unformat (i, "create-vrf"))
8140         create_vrf_if_needed = 1;
8141       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8142         ;
8143       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8144         ;
8145       else
8146         {
8147           clib_warning ("parse error '%U'", format_unformat_error, i);
8148           return -99;
8149         }
8150     }
8151
8152   if (address_set == 0)
8153     {
8154       errmsg ("missing addresses\n");
8155       return -99;
8156     }
8157
8158   /* Construct the API message */
8159   M (IP_MROUTE_ADD_DEL, mp);
8160
8161   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8162   mp->table_id = ntohl (vrf_id);
8163   mp->create_vrf_if_needed = create_vrf_if_needed;
8164
8165   mp->is_add = is_add;
8166   mp->is_ipv6 = is_ipv6;
8167   mp->is_local = is_local;
8168   mp->itf_flags = ntohl (iflags);
8169   mp->entry_flags = ntohl (eflags);
8170   mp->grp_address_length = grp_address_length;
8171   mp->grp_address_length = ntohs (mp->grp_address_length);
8172
8173   if (is_ipv6)
8174     {
8175       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8176       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8177     }
8178   else
8179     {
8180       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8181       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8182
8183     }
8184
8185   /* send it... */
8186   S (mp);
8187   /* Wait for a reply... */
8188   W (ret);
8189   return ret;
8190 }
8191
8192 static int
8193 api_mpls_table_add_del (vat_main_t * vam)
8194 {
8195   unformat_input_t *i = vam->input;
8196   vl_api_mpls_table_add_del_t *mp;
8197   u32 table_id = ~0;
8198   u8 is_add = 1;
8199   int ret = 0;
8200
8201   /* Parse args required to build the message */
8202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8203     {
8204       if (unformat (i, "table %d", &table_id))
8205         ;
8206       else if (unformat (i, "del"))
8207         is_add = 0;
8208       else if (unformat (i, "add"))
8209         is_add = 1;
8210       else
8211         {
8212           clib_warning ("parse error '%U'", format_unformat_error, i);
8213           return -99;
8214         }
8215     }
8216
8217   if (~0 == table_id)
8218     {
8219       errmsg ("missing table-ID");
8220       return -99;
8221     }
8222
8223   /* Construct the API message */
8224   M (MPLS_TABLE_ADD_DEL, mp);
8225
8226   mp->mt_table_id = ntohl (table_id);
8227   mp->mt_is_add = is_add;
8228
8229   /* send it... */
8230   S (mp);
8231
8232   /* Wait for a reply... */
8233   W (ret);
8234
8235   return ret;
8236 }
8237
8238 static int
8239 api_mpls_route_add_del (vat_main_t * vam)
8240 {
8241   unformat_input_t *i = vam->input;
8242   vl_api_mpls_route_add_del_t *mp;
8243   u32 sw_if_index = ~0, table_id = 0;
8244   u8 create_table_if_needed = 0;
8245   u8 is_add = 1;
8246   u32 next_hop_weight = 1;
8247   u8 is_multipath = 0;
8248   u32 next_hop_table_id = 0;
8249   u8 next_hop_set = 0;
8250   ip4_address_t v4_next_hop_address = {
8251     .as_u32 = 0,
8252   };
8253   ip6_address_t v6_next_hop_address = { {0} };
8254   int count = 1;
8255   int j;
8256   f64 before = 0;
8257   u32 classify_table_index = ~0;
8258   u8 is_classify = 0;
8259   u8 resolve_host = 0, resolve_attached = 0;
8260   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8261   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8262   mpls_label_t *next_hop_out_label_stack = NULL;
8263   mpls_label_t local_label = MPLS_LABEL_INVALID;
8264   u8 is_eos = 0;
8265   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8266
8267   /* Parse args required to build the message */
8268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8269     {
8270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8271         ;
8272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8273         ;
8274       else if (unformat (i, "%d", &local_label))
8275         ;
8276       else if (unformat (i, "eos"))
8277         is_eos = 1;
8278       else if (unformat (i, "non-eos"))
8279         is_eos = 0;
8280       else if (unformat (i, "via %U", unformat_ip4_address,
8281                          &v4_next_hop_address))
8282         {
8283           next_hop_set = 1;
8284           next_hop_proto = DPO_PROTO_IP4;
8285         }
8286       else if (unformat (i, "via %U", unformat_ip6_address,
8287                          &v6_next_hop_address))
8288         {
8289           next_hop_set = 1;
8290           next_hop_proto = DPO_PROTO_IP6;
8291         }
8292       else if (unformat (i, "weight %d", &next_hop_weight))
8293         ;
8294       else if (unformat (i, "create-table"))
8295         create_table_if_needed = 1;
8296       else if (unformat (i, "classify %d", &classify_table_index))
8297         {
8298           is_classify = 1;
8299         }
8300       else if (unformat (i, "del"))
8301         is_add = 0;
8302       else if (unformat (i, "add"))
8303         is_add = 1;
8304       else if (unformat (i, "resolve-via-host"))
8305         resolve_host = 1;
8306       else if (unformat (i, "resolve-via-attached"))
8307         resolve_attached = 1;
8308       else if (unformat (i, "multipath"))
8309         is_multipath = 1;
8310       else if (unformat (i, "count %d", &count))
8311         ;
8312       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8313         {
8314           next_hop_set = 1;
8315           next_hop_proto = DPO_PROTO_IP4;
8316         }
8317       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8318         {
8319           next_hop_set = 1;
8320           next_hop_proto = DPO_PROTO_IP6;
8321         }
8322       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8323         ;
8324       else if (unformat (i, "via-label %d", &next_hop_via_label))
8325         ;
8326       else if (unformat (i, "out-label %d", &next_hop_out_label))
8327         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8328       else
8329         {
8330           clib_warning ("parse error '%U'", format_unformat_error, i);
8331           return -99;
8332         }
8333     }
8334
8335   if (!next_hop_set && !is_classify)
8336     {
8337       errmsg ("next hop / classify not set");
8338       return -99;
8339     }
8340
8341   if (MPLS_LABEL_INVALID == local_label)
8342     {
8343       errmsg ("missing label");
8344       return -99;
8345     }
8346
8347   if (count > 1)
8348     {
8349       /* Turn on async mode */
8350       vam->async_mode = 1;
8351       vam->async_errors = 0;
8352       before = vat_time_now (vam);
8353     }
8354
8355   for (j = 0; j < count; j++)
8356     {
8357       /* Construct the API message */
8358       M2 (MPLS_ROUTE_ADD_DEL, mp,
8359           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8360
8361       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8362       mp->mr_table_id = ntohl (table_id);
8363       mp->mr_create_table_if_needed = create_table_if_needed;
8364
8365       mp->mr_is_add = is_add;
8366       mp->mr_next_hop_proto = next_hop_proto;
8367       mp->mr_is_classify = is_classify;
8368       mp->mr_is_multipath = is_multipath;
8369       mp->mr_is_resolve_host = resolve_host;
8370       mp->mr_is_resolve_attached = resolve_attached;
8371       mp->mr_next_hop_weight = next_hop_weight;
8372       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8373       mp->mr_classify_table_index = ntohl (classify_table_index);
8374       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8375       mp->mr_label = ntohl (local_label);
8376       mp->mr_eos = is_eos;
8377
8378       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8379       if (0 != mp->mr_next_hop_n_out_labels)
8380         {
8381           memcpy (mp->mr_next_hop_out_label_stack,
8382                   next_hop_out_label_stack,
8383                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8384           vec_free (next_hop_out_label_stack);
8385         }
8386
8387       if (next_hop_set)
8388         {
8389           if (DPO_PROTO_IP4 == next_hop_proto)
8390             {
8391               clib_memcpy (mp->mr_next_hop,
8392                            &v4_next_hop_address,
8393                            sizeof (v4_next_hop_address));
8394             }
8395           else if (DPO_PROTO_IP6 == next_hop_proto)
8396
8397             {
8398               clib_memcpy (mp->mr_next_hop,
8399                            &v6_next_hop_address,
8400                            sizeof (v6_next_hop_address));
8401             }
8402         }
8403       local_label++;
8404
8405       /* send it... */
8406       S (mp);
8407       /* If we receive SIGTERM, stop now... */
8408       if (vam->do_exit)
8409         break;
8410     }
8411
8412   /* When testing multiple add/del ops, use a control-ping to sync */
8413   if (count > 1)
8414     {
8415       vl_api_control_ping_t *mp_ping;
8416       f64 after;
8417       f64 timeout;
8418
8419       /* Shut off async mode */
8420       vam->async_mode = 0;
8421
8422       MPING (CONTROL_PING, mp_ping);
8423       S (mp_ping);
8424
8425       timeout = vat_time_now (vam) + 1.0;
8426       while (vat_time_now (vam) < timeout)
8427         if (vam->result_ready == 1)
8428           goto out;
8429       vam->retval = -99;
8430
8431     out:
8432       if (vam->retval == -99)
8433         errmsg ("timeout");
8434
8435       if (vam->async_errors > 0)
8436         {
8437           errmsg ("%d asynchronous errors", vam->async_errors);
8438           vam->retval = -98;
8439         }
8440       vam->async_errors = 0;
8441       after = vat_time_now (vam);
8442
8443       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8444       if (j > 0)
8445         count = j;
8446
8447       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8448              count, after - before, count / (after - before));
8449     }
8450   else
8451     {
8452       int ret;
8453
8454       /* Wait for a reply... */
8455       W (ret);
8456       return ret;
8457     }
8458
8459   /* Return the good/bad news */
8460   return (vam->retval);
8461 }
8462
8463 static int
8464 api_mpls_ip_bind_unbind (vat_main_t * vam)
8465 {
8466   unformat_input_t *i = vam->input;
8467   vl_api_mpls_ip_bind_unbind_t *mp;
8468   u32 ip_table_id = 0;
8469   u8 create_table_if_needed = 0;
8470   u8 is_bind = 1;
8471   u8 is_ip4 = 1;
8472   ip4_address_t v4_address;
8473   ip6_address_t v6_address;
8474   u32 address_length;
8475   u8 address_set = 0;
8476   mpls_label_t local_label = MPLS_LABEL_INVALID;
8477   int ret;
8478
8479   /* Parse args required to build the message */
8480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8481     {
8482       if (unformat (i, "%U/%d", unformat_ip4_address,
8483                     &v4_address, &address_length))
8484         {
8485           is_ip4 = 1;
8486           address_set = 1;
8487         }
8488       else if (unformat (i, "%U/%d", unformat_ip6_address,
8489                          &v6_address, &address_length))
8490         {
8491           is_ip4 = 0;
8492           address_set = 1;
8493         }
8494       else if (unformat (i, "%d", &local_label))
8495         ;
8496       else if (unformat (i, "create-table"))
8497         create_table_if_needed = 1;
8498       else if (unformat (i, "table-id %d", &ip_table_id))
8499         ;
8500       else if (unformat (i, "unbind"))
8501         is_bind = 0;
8502       else if (unformat (i, "bind"))
8503         is_bind = 1;
8504       else
8505         {
8506           clib_warning ("parse error '%U'", format_unformat_error, i);
8507           return -99;
8508         }
8509     }
8510
8511   if (!address_set)
8512     {
8513       errmsg ("IP addres not set");
8514       return -99;
8515     }
8516
8517   if (MPLS_LABEL_INVALID == local_label)
8518     {
8519       errmsg ("missing label");
8520       return -99;
8521     }
8522
8523   /* Construct the API message */
8524   M (MPLS_IP_BIND_UNBIND, mp);
8525
8526   mp->mb_create_table_if_needed = create_table_if_needed;
8527   mp->mb_is_bind = is_bind;
8528   mp->mb_is_ip4 = is_ip4;
8529   mp->mb_ip_table_id = ntohl (ip_table_id);
8530   mp->mb_mpls_table_id = 0;
8531   mp->mb_label = ntohl (local_label);
8532   mp->mb_address_length = address_length;
8533
8534   if (is_ip4)
8535     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8536   else
8537     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8538
8539   /* send it... */
8540   S (mp);
8541
8542   /* Wait for a reply... */
8543   W (ret);
8544   return ret;
8545 }
8546
8547 static int
8548 api_proxy_arp_add_del (vat_main_t * vam)
8549 {
8550   unformat_input_t *i = vam->input;
8551   vl_api_proxy_arp_add_del_t *mp;
8552   u32 vrf_id = 0;
8553   u8 is_add = 1;
8554   ip4_address_t lo, hi;
8555   u8 range_set = 0;
8556   int ret;
8557
8558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8559     {
8560       if (unformat (i, "vrf %d", &vrf_id))
8561         ;
8562       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8563                          unformat_ip4_address, &hi))
8564         range_set = 1;
8565       else if (unformat (i, "del"))
8566         is_add = 0;
8567       else
8568         {
8569           clib_warning ("parse error '%U'", format_unformat_error, i);
8570           return -99;
8571         }
8572     }
8573
8574   if (range_set == 0)
8575     {
8576       errmsg ("address range not set");
8577       return -99;
8578     }
8579
8580   M (PROXY_ARP_ADD_DEL, mp);
8581
8582   mp->vrf_id = ntohl (vrf_id);
8583   mp->is_add = is_add;
8584   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8585   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8586
8587   S (mp);
8588   W (ret);
8589   return ret;
8590 }
8591
8592 static int
8593 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8594 {
8595   unformat_input_t *i = vam->input;
8596   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8597   u32 sw_if_index;
8598   u8 enable = 1;
8599   u8 sw_if_index_set = 0;
8600   int ret;
8601
8602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8603     {
8604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8605         sw_if_index_set = 1;
8606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8607         sw_if_index_set = 1;
8608       else if (unformat (i, "enable"))
8609         enable = 1;
8610       else if (unformat (i, "disable"))
8611         enable = 0;
8612       else
8613         {
8614           clib_warning ("parse error '%U'", format_unformat_error, i);
8615           return -99;
8616         }
8617     }
8618
8619   if (sw_if_index_set == 0)
8620     {
8621       errmsg ("missing interface name or sw_if_index");
8622       return -99;
8623     }
8624
8625   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8626
8627   mp->sw_if_index = ntohl (sw_if_index);
8628   mp->enable_disable = enable;
8629
8630   S (mp);
8631   W (ret);
8632   return ret;
8633 }
8634
8635 static int
8636 api_mpls_tunnel_add_del (vat_main_t * vam)
8637 {
8638   unformat_input_t *i = vam->input;
8639   vl_api_mpls_tunnel_add_del_t *mp;
8640
8641   u8 is_add = 1;
8642   u8 l2_only = 0;
8643   u32 sw_if_index = ~0;
8644   u32 next_hop_sw_if_index = ~0;
8645   u32 next_hop_proto_is_ip4 = 1;
8646
8647   u32 next_hop_table_id = 0;
8648   ip4_address_t v4_next_hop_address = {
8649     .as_u32 = 0,
8650   };
8651   ip6_address_t v6_next_hop_address = { {0} };
8652   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8653   int ret;
8654
8655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8656     {
8657       if (unformat (i, "add"))
8658         is_add = 1;
8659       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8660         is_add = 0;
8661       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8662         ;
8663       else if (unformat (i, "via %U",
8664                          unformat_ip4_address, &v4_next_hop_address))
8665         {
8666           next_hop_proto_is_ip4 = 1;
8667         }
8668       else if (unformat (i, "via %U",
8669                          unformat_ip6_address, &v6_next_hop_address))
8670         {
8671           next_hop_proto_is_ip4 = 0;
8672         }
8673       else if (unformat (i, "l2-only"))
8674         l2_only = 1;
8675       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8676         ;
8677       else if (unformat (i, "out-label %d", &next_hop_out_label))
8678         vec_add1 (labels, ntohl (next_hop_out_label));
8679       else
8680         {
8681           clib_warning ("parse error '%U'", format_unformat_error, i);
8682           return -99;
8683         }
8684     }
8685
8686   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8687
8688   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8689   mp->mt_sw_if_index = ntohl (sw_if_index);
8690   mp->mt_is_add = is_add;
8691   mp->mt_l2_only = l2_only;
8692   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8693   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8694
8695   mp->mt_next_hop_n_out_labels = vec_len (labels);
8696
8697   if (0 != mp->mt_next_hop_n_out_labels)
8698     {
8699       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8700                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8701       vec_free (labels);
8702     }
8703
8704   if (next_hop_proto_is_ip4)
8705     {
8706       clib_memcpy (mp->mt_next_hop,
8707                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8708     }
8709   else
8710     {
8711       clib_memcpy (mp->mt_next_hop,
8712                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8713     }
8714
8715   S (mp);
8716   W (ret);
8717   return ret;
8718 }
8719
8720 static int
8721 api_sw_interface_set_unnumbered (vat_main_t * vam)
8722 {
8723   unformat_input_t *i = vam->input;
8724   vl_api_sw_interface_set_unnumbered_t *mp;
8725   u32 sw_if_index;
8726   u32 unnum_sw_index = ~0;
8727   u8 is_add = 1;
8728   u8 sw_if_index_set = 0;
8729   int ret;
8730
8731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8732     {
8733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8734         sw_if_index_set = 1;
8735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8736         sw_if_index_set = 1;
8737       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8738         ;
8739       else if (unformat (i, "del"))
8740         is_add = 0;
8741       else
8742         {
8743           clib_warning ("parse error '%U'", format_unformat_error, i);
8744           return -99;
8745         }
8746     }
8747
8748   if (sw_if_index_set == 0)
8749     {
8750       errmsg ("missing interface name or sw_if_index");
8751       return -99;
8752     }
8753
8754   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8755
8756   mp->sw_if_index = ntohl (sw_if_index);
8757   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8758   mp->is_add = is_add;
8759
8760   S (mp);
8761   W (ret);
8762   return ret;
8763 }
8764
8765 static int
8766 api_ip_neighbor_add_del (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_ip_neighbor_add_del_t *mp;
8770   u32 sw_if_index;
8771   u8 sw_if_index_set = 0;
8772   u8 is_add = 1;
8773   u8 is_static = 0;
8774   u8 is_no_fib_entry = 0;
8775   u8 mac_address[6];
8776   u8 mac_set = 0;
8777   u8 v4_address_set = 0;
8778   u8 v6_address_set = 0;
8779   ip4_address_t v4address;
8780   ip6_address_t v6address;
8781   int ret;
8782
8783   memset (mac_address, 0, sizeof (mac_address));
8784
8785   /* Parse args required to build the message */
8786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8787     {
8788       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8789         {
8790           mac_set = 1;
8791         }
8792       else if (unformat (i, "del"))
8793         is_add = 0;
8794       else
8795         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8796         sw_if_index_set = 1;
8797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8798         sw_if_index_set = 1;
8799       else if (unformat (i, "is_static"))
8800         is_static = 1;
8801       else if (unformat (i, "no-fib-entry"))
8802         is_no_fib_entry = 1;
8803       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8804         v4_address_set = 1;
8805       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8806         v6_address_set = 1;
8807       else
8808         {
8809           clib_warning ("parse error '%U'", format_unformat_error, i);
8810           return -99;
8811         }
8812     }
8813
8814   if (sw_if_index_set == 0)
8815     {
8816       errmsg ("missing interface name or sw_if_index");
8817       return -99;
8818     }
8819   if (v4_address_set && v6_address_set)
8820     {
8821       errmsg ("both v4 and v6 addresses set");
8822       return -99;
8823     }
8824   if (!v4_address_set && !v6_address_set)
8825     {
8826       errmsg ("no address set");
8827       return -99;
8828     }
8829
8830   /* Construct the API message */
8831   M (IP_NEIGHBOR_ADD_DEL, mp);
8832
8833   mp->sw_if_index = ntohl (sw_if_index);
8834   mp->is_add = is_add;
8835   mp->is_static = is_static;
8836   mp->is_no_adj_fib = is_no_fib_entry;
8837   if (mac_set)
8838     clib_memcpy (mp->mac_address, mac_address, 6);
8839   if (v6_address_set)
8840     {
8841       mp->is_ipv6 = 1;
8842       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8843     }
8844   else
8845     {
8846       /* mp->is_ipv6 = 0; via memset in M macro above */
8847       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8848     }
8849
8850   /* send it... */
8851   S (mp);
8852
8853   /* Wait for a reply, return good/bad news  */
8854   W (ret);
8855   return ret;
8856 }
8857
8858 static int
8859 api_reset_vrf (vat_main_t * vam)
8860 {
8861   unformat_input_t *i = vam->input;
8862   vl_api_reset_vrf_t *mp;
8863   u32 vrf_id = 0;
8864   u8 is_ipv6 = 0;
8865   u8 vrf_id_set = 0;
8866   int ret;
8867
8868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (i, "vrf %d", &vrf_id))
8871         vrf_id_set = 1;
8872       else if (unformat (i, "ipv6"))
8873         is_ipv6 = 1;
8874       else
8875         {
8876           clib_warning ("parse error '%U'", format_unformat_error, i);
8877           return -99;
8878         }
8879     }
8880
8881   if (vrf_id_set == 0)
8882     {
8883       errmsg ("missing vrf id");
8884       return -99;
8885     }
8886
8887   M (RESET_VRF, mp);
8888
8889   mp->vrf_id = ntohl (vrf_id);
8890   mp->is_ipv6 = is_ipv6;
8891
8892   S (mp);
8893   W (ret);
8894   return ret;
8895 }
8896
8897 static int
8898 api_create_vlan_subif (vat_main_t * vam)
8899 {
8900   unformat_input_t *i = vam->input;
8901   vl_api_create_vlan_subif_t *mp;
8902   u32 sw_if_index;
8903   u8 sw_if_index_set = 0;
8904   u32 vlan_id;
8905   u8 vlan_id_set = 0;
8906   int ret;
8907
8908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8909     {
8910       if (unformat (i, "sw_if_index %d", &sw_if_index))
8911         sw_if_index_set = 1;
8912       else
8913         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8914         sw_if_index_set = 1;
8915       else if (unformat (i, "vlan %d", &vlan_id))
8916         vlan_id_set = 1;
8917       else
8918         {
8919           clib_warning ("parse error '%U'", format_unformat_error, i);
8920           return -99;
8921         }
8922     }
8923
8924   if (sw_if_index_set == 0)
8925     {
8926       errmsg ("missing interface name or sw_if_index");
8927       return -99;
8928     }
8929
8930   if (vlan_id_set == 0)
8931     {
8932       errmsg ("missing vlan_id");
8933       return -99;
8934     }
8935   M (CREATE_VLAN_SUBIF, mp);
8936
8937   mp->sw_if_index = ntohl (sw_if_index);
8938   mp->vlan_id = ntohl (vlan_id);
8939
8940   S (mp);
8941   W (ret);
8942   return ret;
8943 }
8944
8945 #define foreach_create_subif_bit                \
8946 _(no_tags)                                      \
8947 _(one_tag)                                      \
8948 _(two_tags)                                     \
8949 _(dot1ad)                                       \
8950 _(exact_match)                                  \
8951 _(default_sub)                                  \
8952 _(outer_vlan_id_any)                            \
8953 _(inner_vlan_id_any)
8954
8955 static int
8956 api_create_subif (vat_main_t * vam)
8957 {
8958   unformat_input_t *i = vam->input;
8959   vl_api_create_subif_t *mp;
8960   u32 sw_if_index;
8961   u8 sw_if_index_set = 0;
8962   u32 sub_id;
8963   u8 sub_id_set = 0;
8964   u32 no_tags = 0;
8965   u32 one_tag = 0;
8966   u32 two_tags = 0;
8967   u32 dot1ad = 0;
8968   u32 exact_match = 0;
8969   u32 default_sub = 0;
8970   u32 outer_vlan_id_any = 0;
8971   u32 inner_vlan_id_any = 0;
8972   u32 tmp;
8973   u16 outer_vlan_id = 0;
8974   u16 inner_vlan_id = 0;
8975   int ret;
8976
8977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (i, "sw_if_index %d", &sw_if_index))
8980         sw_if_index_set = 1;
8981       else
8982         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8983         sw_if_index_set = 1;
8984       else if (unformat (i, "sub_id %d", &sub_id))
8985         sub_id_set = 1;
8986       else if (unformat (i, "outer_vlan_id %d", &tmp))
8987         outer_vlan_id = tmp;
8988       else if (unformat (i, "inner_vlan_id %d", &tmp))
8989         inner_vlan_id = tmp;
8990
8991 #define _(a) else if (unformat (i, #a)) a = 1 ;
8992       foreach_create_subif_bit
8993 #undef _
8994         else
8995         {
8996           clib_warning ("parse error '%U'", format_unformat_error, i);
8997           return -99;
8998         }
8999     }
9000
9001   if (sw_if_index_set == 0)
9002     {
9003       errmsg ("missing interface name or sw_if_index");
9004       return -99;
9005     }
9006
9007   if (sub_id_set == 0)
9008     {
9009       errmsg ("missing sub_id");
9010       return -99;
9011     }
9012   M (CREATE_SUBIF, mp);
9013
9014   mp->sw_if_index = ntohl (sw_if_index);
9015   mp->sub_id = ntohl (sub_id);
9016
9017 #define _(a) mp->a = a;
9018   foreach_create_subif_bit;
9019 #undef _
9020
9021   mp->outer_vlan_id = ntohs (outer_vlan_id);
9022   mp->inner_vlan_id = ntohs (inner_vlan_id);
9023
9024   S (mp);
9025   W (ret);
9026   return ret;
9027 }
9028
9029 static int
9030 api_oam_add_del (vat_main_t * vam)
9031 {
9032   unformat_input_t *i = vam->input;
9033   vl_api_oam_add_del_t *mp;
9034   u32 vrf_id = 0;
9035   u8 is_add = 1;
9036   ip4_address_t src, dst;
9037   u8 src_set = 0;
9038   u8 dst_set = 0;
9039   int ret;
9040
9041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (i, "vrf %d", &vrf_id))
9044         ;
9045       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9046         src_set = 1;
9047       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9048         dst_set = 1;
9049       else if (unformat (i, "del"))
9050         is_add = 0;
9051       else
9052         {
9053           clib_warning ("parse error '%U'", format_unformat_error, i);
9054           return -99;
9055         }
9056     }
9057
9058   if (src_set == 0)
9059     {
9060       errmsg ("missing src addr");
9061       return -99;
9062     }
9063
9064   if (dst_set == 0)
9065     {
9066       errmsg ("missing dst addr");
9067       return -99;
9068     }
9069
9070   M (OAM_ADD_DEL, mp);
9071
9072   mp->vrf_id = ntohl (vrf_id);
9073   mp->is_add = is_add;
9074   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9075   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9076
9077   S (mp);
9078   W (ret);
9079   return ret;
9080 }
9081
9082 static int
9083 api_reset_fib (vat_main_t * vam)
9084 {
9085   unformat_input_t *i = vam->input;
9086   vl_api_reset_fib_t *mp;
9087   u32 vrf_id = 0;
9088   u8 is_ipv6 = 0;
9089   u8 vrf_id_set = 0;
9090
9091   int ret;
9092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9093     {
9094       if (unformat (i, "vrf %d", &vrf_id))
9095         vrf_id_set = 1;
9096       else if (unformat (i, "ipv6"))
9097         is_ipv6 = 1;
9098       else
9099         {
9100           clib_warning ("parse error '%U'", format_unformat_error, i);
9101           return -99;
9102         }
9103     }
9104
9105   if (vrf_id_set == 0)
9106     {
9107       errmsg ("missing vrf id");
9108       return -99;
9109     }
9110
9111   M (RESET_FIB, mp);
9112
9113   mp->vrf_id = ntohl (vrf_id);
9114   mp->is_ipv6 = is_ipv6;
9115
9116   S (mp);
9117   W (ret);
9118   return ret;
9119 }
9120
9121 static int
9122 api_dhcp_proxy_config (vat_main_t * vam)
9123 {
9124   unformat_input_t *i = vam->input;
9125   vl_api_dhcp_proxy_config_t *mp;
9126   u32 rx_vrf_id = 0;
9127   u32 server_vrf_id = 0;
9128   u8 is_add = 1;
9129   u8 v4_address_set = 0;
9130   u8 v6_address_set = 0;
9131   ip4_address_t v4address;
9132   ip6_address_t v6address;
9133   u8 v4_src_address_set = 0;
9134   u8 v6_src_address_set = 0;
9135   ip4_address_t v4srcaddress;
9136   ip6_address_t v6srcaddress;
9137   int ret;
9138
9139   /* Parse args required to build the message */
9140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9141     {
9142       if (unformat (i, "del"))
9143         is_add = 0;
9144       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9145         ;
9146       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9147         ;
9148       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9149         v4_address_set = 1;
9150       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9151         v6_address_set = 1;
9152       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9153         v4_src_address_set = 1;
9154       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9155         v6_src_address_set = 1;
9156       else
9157         break;
9158     }
9159
9160   if (v4_address_set && v6_address_set)
9161     {
9162       errmsg ("both v4 and v6 server addresses set");
9163       return -99;
9164     }
9165   if (!v4_address_set && !v6_address_set)
9166     {
9167       errmsg ("no server addresses set");
9168       return -99;
9169     }
9170
9171   if (v4_src_address_set && v6_src_address_set)
9172     {
9173       errmsg ("both v4 and v6  src addresses set");
9174       return -99;
9175     }
9176   if (!v4_src_address_set && !v6_src_address_set)
9177     {
9178       errmsg ("no src addresses set");
9179       return -99;
9180     }
9181
9182   if (!(v4_src_address_set && v4_address_set) &&
9183       !(v6_src_address_set && v6_address_set))
9184     {
9185       errmsg ("no matching server and src addresses set");
9186       return -99;
9187     }
9188
9189   /* Construct the API message */
9190   M (DHCP_PROXY_CONFIG, mp);
9191
9192   mp->is_add = is_add;
9193   mp->rx_vrf_id = ntohl (rx_vrf_id);
9194   mp->server_vrf_id = ntohl (server_vrf_id);
9195   if (v6_address_set)
9196     {
9197       mp->is_ipv6 = 1;
9198       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9199       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9200     }
9201   else
9202     {
9203       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9204       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9205     }
9206
9207   /* send it... */
9208   S (mp);
9209
9210   /* Wait for a reply, return good/bad news  */
9211   W (ret);
9212   return ret;
9213 }
9214
9215 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9216 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9217
9218 static void
9219 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9220 {
9221   vat_main_t *vam = &vat_main;
9222   u32 i, count = mp->count;
9223   vl_api_dhcp_server_t *s;
9224
9225   if (mp->is_ipv6)
9226     print (vam->ofp,
9227            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9228            ntohl (mp->rx_vrf_id),
9229            format_ip6_address, mp->dhcp_src_address,
9230            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9231   else
9232     print (vam->ofp,
9233            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9234            ntohl (mp->rx_vrf_id),
9235            format_ip4_address, mp->dhcp_src_address,
9236            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9237
9238   for (i = 0; i < count; i++)
9239     {
9240       s = &mp->servers[i];
9241
9242       if (mp->is_ipv6)
9243         print (vam->ofp,
9244                " Server Table-ID %d, Server Address %U",
9245                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9246       else
9247         print (vam->ofp,
9248                " Server Table-ID %d, Server Address %U",
9249                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9250     }
9251 }
9252
9253 static void vl_api_dhcp_proxy_details_t_handler_json
9254   (vl_api_dhcp_proxy_details_t * mp)
9255 {
9256   vat_main_t *vam = &vat_main;
9257   vat_json_node_t *node = NULL;
9258   u32 i, count = mp->count;
9259   struct in_addr ip4;
9260   struct in6_addr ip6;
9261   vl_api_dhcp_server_t *s;
9262
9263   if (VAT_JSON_ARRAY != vam->json_tree.type)
9264     {
9265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9266       vat_json_init_array (&vam->json_tree);
9267     }
9268   node = vat_json_array_add (&vam->json_tree);
9269
9270   vat_json_init_object (node);
9271   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9272   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9273   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9274
9275   if (mp->is_ipv6)
9276     {
9277       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9278       vat_json_object_add_ip6 (node, "src_address", ip6);
9279     }
9280   else
9281     {
9282       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9283       vat_json_object_add_ip4 (node, "src_address", ip4);
9284     }
9285
9286   for (i = 0; i < count; i++)
9287     {
9288       s = &mp->servers[i];
9289
9290       vat_json_object_add_uint (node, "server-table-id",
9291                                 ntohl (s->server_vrf_id));
9292
9293       if (mp->is_ipv6)
9294         {
9295           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9296           vat_json_object_add_ip4 (node, "src_address", ip4);
9297         }
9298       else
9299         {
9300           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9301           vat_json_object_add_ip6 (node, "server_address", ip6);
9302         }
9303     }
9304 }
9305
9306 static int
9307 api_dhcp_proxy_dump (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_control_ping_t *mp_ping;
9311   vl_api_dhcp_proxy_dump_t *mp;
9312   u8 is_ipv6 = 0;
9313   int ret;
9314
9315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9316     {
9317       if (unformat (i, "ipv6"))
9318         is_ipv6 = 1;
9319       else
9320         {
9321           clib_warning ("parse error '%U'", format_unformat_error, i);
9322           return -99;
9323         }
9324     }
9325
9326   M (DHCP_PROXY_DUMP, mp);
9327
9328   mp->is_ip6 = is_ipv6;
9329   S (mp);
9330
9331   /* Use a control ping for synchronization */
9332   MPING (CONTROL_PING, mp_ping);
9333   S (mp_ping);
9334
9335   W (ret);
9336   return ret;
9337 }
9338
9339 static int
9340 api_dhcp_proxy_set_vss (vat_main_t * vam)
9341 {
9342   unformat_input_t *i = vam->input;
9343   vl_api_dhcp_proxy_set_vss_t *mp;
9344   u8 is_ipv6 = 0;
9345   u8 is_add = 1;
9346   u32 tbl_id;
9347   u8 tbl_id_set = 0;
9348   u32 oui;
9349   u8 oui_set = 0;
9350   u32 fib_id;
9351   u8 fib_id_set = 0;
9352   int ret;
9353
9354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9355     {
9356       if (unformat (i, "tbl_id %d", &tbl_id))
9357         tbl_id_set = 1;
9358       if (unformat (i, "fib_id %d", &fib_id))
9359         fib_id_set = 1;
9360       if (unformat (i, "oui %d", &oui))
9361         oui_set = 1;
9362       else if (unformat (i, "ipv6"))
9363         is_ipv6 = 1;
9364       else if (unformat (i, "del"))
9365         is_add = 0;
9366       else
9367         {
9368           clib_warning ("parse error '%U'", format_unformat_error, i);
9369           return -99;
9370         }
9371     }
9372
9373   if (tbl_id_set == 0)
9374     {
9375       errmsg ("missing tbl id");
9376       return -99;
9377     }
9378
9379   if (fib_id_set == 0)
9380     {
9381       errmsg ("missing fib id");
9382       return -99;
9383     }
9384   if (oui_set == 0)
9385     {
9386       errmsg ("missing oui");
9387       return -99;
9388     }
9389
9390   M (DHCP_PROXY_SET_VSS, mp);
9391   mp->tbl_id = ntohl (tbl_id);
9392   mp->fib_id = ntohl (fib_id);
9393   mp->oui = ntohl (oui);
9394   mp->is_ipv6 = is_ipv6;
9395   mp->is_add = is_add;
9396
9397   S (mp);
9398   W (ret);
9399   return ret;
9400 }
9401
9402 static int
9403 api_dhcp_client_config (vat_main_t * vam)
9404 {
9405   unformat_input_t *i = vam->input;
9406   vl_api_dhcp_client_config_t *mp;
9407   u32 sw_if_index;
9408   u8 sw_if_index_set = 0;
9409   u8 is_add = 1;
9410   u8 *hostname = 0;
9411   u8 disable_event = 0;
9412   int ret;
9413
9414   /* Parse args required to build the message */
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "del"))
9418         is_add = 0;
9419       else
9420         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9421         sw_if_index_set = 1;
9422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9423         sw_if_index_set = 1;
9424       else if (unformat (i, "hostname %s", &hostname))
9425         ;
9426       else if (unformat (i, "disable_event"))
9427         disable_event = 1;
9428       else
9429         break;
9430     }
9431
9432   if (sw_if_index_set == 0)
9433     {
9434       errmsg ("missing interface name or sw_if_index");
9435       return -99;
9436     }
9437
9438   if (vec_len (hostname) > 63)
9439     {
9440       errmsg ("hostname too long");
9441     }
9442   vec_add1 (hostname, 0);
9443
9444   /* Construct the API message */
9445   M (DHCP_CLIENT_CONFIG, mp);
9446
9447   mp->sw_if_index = htonl (sw_if_index);
9448   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9449   vec_free (hostname);
9450   mp->is_add = is_add;
9451   mp->want_dhcp_event = disable_event ? 0 : 1;
9452   mp->pid = htonl (getpid ());
9453
9454   /* send it... */
9455   S (mp);
9456
9457   /* Wait for a reply, return good/bad news  */
9458   W (ret);
9459   return ret;
9460 }
9461
9462 static int
9463 api_set_ip_flow_hash (vat_main_t * vam)
9464 {
9465   unformat_input_t *i = vam->input;
9466   vl_api_set_ip_flow_hash_t *mp;
9467   u32 vrf_id = 0;
9468   u8 is_ipv6 = 0;
9469   u8 vrf_id_set = 0;
9470   u8 src = 0;
9471   u8 dst = 0;
9472   u8 sport = 0;
9473   u8 dport = 0;
9474   u8 proto = 0;
9475   u8 reverse = 0;
9476   int ret;
9477
9478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9479     {
9480       if (unformat (i, "vrf %d", &vrf_id))
9481         vrf_id_set = 1;
9482       else if (unformat (i, "ipv6"))
9483         is_ipv6 = 1;
9484       else if (unformat (i, "src"))
9485         src = 1;
9486       else if (unformat (i, "dst"))
9487         dst = 1;
9488       else if (unformat (i, "sport"))
9489         sport = 1;
9490       else if (unformat (i, "dport"))
9491         dport = 1;
9492       else if (unformat (i, "proto"))
9493         proto = 1;
9494       else if (unformat (i, "reverse"))
9495         reverse = 1;
9496
9497       else
9498         {
9499           clib_warning ("parse error '%U'", format_unformat_error, i);
9500           return -99;
9501         }
9502     }
9503
9504   if (vrf_id_set == 0)
9505     {
9506       errmsg ("missing vrf id");
9507       return -99;
9508     }
9509
9510   M (SET_IP_FLOW_HASH, mp);
9511   mp->src = src;
9512   mp->dst = dst;
9513   mp->sport = sport;
9514   mp->dport = dport;
9515   mp->proto = proto;
9516   mp->reverse = reverse;
9517   mp->vrf_id = ntohl (vrf_id);
9518   mp->is_ipv6 = is_ipv6;
9519
9520   S (mp);
9521   W (ret);
9522   return ret;
9523 }
9524
9525 static int
9526 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9527 {
9528   unformat_input_t *i = vam->input;
9529   vl_api_sw_interface_ip6_enable_disable_t *mp;
9530   u32 sw_if_index;
9531   u8 sw_if_index_set = 0;
9532   u8 enable = 0;
9533   int ret;
9534
9535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9536     {
9537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9538         sw_if_index_set = 1;
9539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9540         sw_if_index_set = 1;
9541       else if (unformat (i, "enable"))
9542         enable = 1;
9543       else if (unformat (i, "disable"))
9544         enable = 0;
9545       else
9546         {
9547           clib_warning ("parse error '%U'", format_unformat_error, i);
9548           return -99;
9549         }
9550     }
9551
9552   if (sw_if_index_set == 0)
9553     {
9554       errmsg ("missing interface name or sw_if_index");
9555       return -99;
9556     }
9557
9558   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9559
9560   mp->sw_if_index = ntohl (sw_if_index);
9561   mp->enable = enable;
9562
9563   S (mp);
9564   W (ret);
9565   return ret;
9566 }
9567
9568 static int
9569 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9570 {
9571   unformat_input_t *i = vam->input;
9572   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9573   u32 sw_if_index;
9574   u8 sw_if_index_set = 0;
9575   u8 v6_address_set = 0;
9576   ip6_address_t v6address;
9577   int ret;
9578
9579   /* Parse args required to build the message */
9580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9581     {
9582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9583         sw_if_index_set = 1;
9584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9585         sw_if_index_set = 1;
9586       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9587         v6_address_set = 1;
9588       else
9589         break;
9590     }
9591
9592   if (sw_if_index_set == 0)
9593     {
9594       errmsg ("missing interface name or sw_if_index");
9595       return -99;
9596     }
9597   if (!v6_address_set)
9598     {
9599       errmsg ("no address set");
9600       return -99;
9601     }
9602
9603   /* Construct the API message */
9604   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9605
9606   mp->sw_if_index = ntohl (sw_if_index);
9607   clib_memcpy (mp->address, &v6address, sizeof (v6address));
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_ip6nd_proxy_add_del (vat_main_t * vam)
9619 {
9620   unformat_input_t *i = vam->input;
9621   vl_api_ip6nd_proxy_add_del_t *mp;
9622   u32 sw_if_index = ~0;
9623   u8 v6_address_set = 0;
9624   ip6_address_t v6address;
9625   u8 is_del = 0;
9626   int ret;
9627
9628   /* Parse args required to build the message */
9629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9630     {
9631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9632         ;
9633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9634         ;
9635       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9636         v6_address_set = 1;
9637       if (unformat (i, "del"))
9638         is_del = 1;
9639       else
9640         {
9641           clib_warning ("parse error '%U'", format_unformat_error, i);
9642           return -99;
9643         }
9644     }
9645
9646   if (sw_if_index == ~0)
9647     {
9648       errmsg ("missing interface name or sw_if_index");
9649       return -99;
9650     }
9651   if (!v6_address_set)
9652     {
9653       errmsg ("no address set");
9654       return -99;
9655     }
9656
9657   /* Construct the API message */
9658   M (IP6ND_PROXY_ADD_DEL, mp);
9659
9660   mp->is_del = is_del;
9661   mp->sw_if_index = ntohl (sw_if_index);
9662   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9663
9664   /* send it... */
9665   S (mp);
9666
9667   /* Wait for a reply, return good/bad news  */
9668   W (ret);
9669   return ret;
9670 }
9671
9672 static int
9673 api_ip6nd_proxy_dump (vat_main_t * vam)
9674 {
9675   vl_api_ip6nd_proxy_dump_t *mp;
9676   vl_api_control_ping_t *mp_ping;
9677   int ret;
9678
9679   M (IP6ND_PROXY_DUMP, mp);
9680
9681   S (mp);
9682
9683   /* Use a control ping for synchronization */
9684   MPING (CONTROL_PING, mp_ping);
9685   S (mp_ping);
9686
9687   W (ret);
9688   return ret;
9689 }
9690
9691 static void vl_api_ip6nd_proxy_details_t_handler
9692   (vl_api_ip6nd_proxy_details_t * mp)
9693 {
9694   vat_main_t *vam = &vat_main;
9695
9696   print (vam->ofp, "host %U sw_if_index %d",
9697          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9698 }
9699
9700 static void vl_api_ip6nd_proxy_details_t_handler_json
9701   (vl_api_ip6nd_proxy_details_t * mp)
9702 {
9703   vat_main_t *vam = &vat_main;
9704   struct in6_addr ip6;
9705   vat_json_node_t *node = NULL;
9706
9707   if (VAT_JSON_ARRAY != vam->json_tree.type)
9708     {
9709       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9710       vat_json_init_array (&vam->json_tree);
9711     }
9712   node = vat_json_array_add (&vam->json_tree);
9713
9714   vat_json_init_object (node);
9715   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9716
9717   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9718   vat_json_object_add_ip6 (node, "host", ip6);
9719 }
9720
9721 static int
9722 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9723 {
9724   unformat_input_t *i = vam->input;
9725   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9726   u32 sw_if_index;
9727   u8 sw_if_index_set = 0;
9728   u32 address_length = 0;
9729   u8 v6_address_set = 0;
9730   ip6_address_t v6address;
9731   u8 use_default = 0;
9732   u8 no_advertise = 0;
9733   u8 off_link = 0;
9734   u8 no_autoconfig = 0;
9735   u8 no_onlink = 0;
9736   u8 is_no = 0;
9737   u32 val_lifetime = 0;
9738   u32 pref_lifetime = 0;
9739   int ret;
9740
9741   /* Parse args required to build the message */
9742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9743     {
9744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9745         sw_if_index_set = 1;
9746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9747         sw_if_index_set = 1;
9748       else if (unformat (i, "%U/%d",
9749                          unformat_ip6_address, &v6address, &address_length))
9750         v6_address_set = 1;
9751       else if (unformat (i, "val_life %d", &val_lifetime))
9752         ;
9753       else if (unformat (i, "pref_life %d", &pref_lifetime))
9754         ;
9755       else if (unformat (i, "def"))
9756         use_default = 1;
9757       else if (unformat (i, "noadv"))
9758         no_advertise = 1;
9759       else if (unformat (i, "offl"))
9760         off_link = 1;
9761       else if (unformat (i, "noauto"))
9762         no_autoconfig = 1;
9763       else if (unformat (i, "nolink"))
9764         no_onlink = 1;
9765       else if (unformat (i, "isno"))
9766         is_no = 1;
9767       else
9768         {
9769           clib_warning ("parse error '%U'", format_unformat_error, i);
9770           return -99;
9771         }
9772     }
9773
9774   if (sw_if_index_set == 0)
9775     {
9776       errmsg ("missing interface name or sw_if_index");
9777       return -99;
9778     }
9779   if (!v6_address_set)
9780     {
9781       errmsg ("no address set");
9782       return -99;
9783     }
9784
9785   /* Construct the API message */
9786   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9787
9788   mp->sw_if_index = ntohl (sw_if_index);
9789   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9790   mp->address_length = address_length;
9791   mp->use_default = use_default;
9792   mp->no_advertise = no_advertise;
9793   mp->off_link = off_link;
9794   mp->no_autoconfig = no_autoconfig;
9795   mp->no_onlink = no_onlink;
9796   mp->is_no = is_no;
9797   mp->val_lifetime = ntohl (val_lifetime);
9798   mp->pref_lifetime = ntohl (pref_lifetime);
9799
9800   /* send it... */
9801   S (mp);
9802
9803   /* Wait for a reply, return good/bad news  */
9804   W (ret);
9805   return ret;
9806 }
9807
9808 static int
9809 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9810 {
9811   unformat_input_t *i = vam->input;
9812   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9813   u32 sw_if_index;
9814   u8 sw_if_index_set = 0;
9815   u8 suppress = 0;
9816   u8 managed = 0;
9817   u8 other = 0;
9818   u8 ll_option = 0;
9819   u8 send_unicast = 0;
9820   u8 cease = 0;
9821   u8 is_no = 0;
9822   u8 default_router = 0;
9823   u32 max_interval = 0;
9824   u32 min_interval = 0;
9825   u32 lifetime = 0;
9826   u32 initial_count = 0;
9827   u32 initial_interval = 0;
9828   int ret;
9829
9830
9831   /* Parse args required to build the message */
9832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9833     {
9834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9835         sw_if_index_set = 1;
9836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9837         sw_if_index_set = 1;
9838       else if (unformat (i, "maxint %d", &max_interval))
9839         ;
9840       else if (unformat (i, "minint %d", &min_interval))
9841         ;
9842       else if (unformat (i, "life %d", &lifetime))
9843         ;
9844       else if (unformat (i, "count %d", &initial_count))
9845         ;
9846       else if (unformat (i, "interval %d", &initial_interval))
9847         ;
9848       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9849         suppress = 1;
9850       else if (unformat (i, "managed"))
9851         managed = 1;
9852       else if (unformat (i, "other"))
9853         other = 1;
9854       else if (unformat (i, "ll"))
9855         ll_option = 1;
9856       else if (unformat (i, "send"))
9857         send_unicast = 1;
9858       else if (unformat (i, "cease"))
9859         cease = 1;
9860       else if (unformat (i, "isno"))
9861         is_no = 1;
9862       else if (unformat (i, "def"))
9863         default_router = 1;
9864       else
9865         {
9866           clib_warning ("parse error '%U'", format_unformat_error, i);
9867           return -99;
9868         }
9869     }
9870
9871   if (sw_if_index_set == 0)
9872     {
9873       errmsg ("missing interface name or sw_if_index");
9874       return -99;
9875     }
9876
9877   /* Construct the API message */
9878   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9879
9880   mp->sw_if_index = ntohl (sw_if_index);
9881   mp->max_interval = ntohl (max_interval);
9882   mp->min_interval = ntohl (min_interval);
9883   mp->lifetime = ntohl (lifetime);
9884   mp->initial_count = ntohl (initial_count);
9885   mp->initial_interval = ntohl (initial_interval);
9886   mp->suppress = suppress;
9887   mp->managed = managed;
9888   mp->other = other;
9889   mp->ll_option = ll_option;
9890   mp->send_unicast = send_unicast;
9891   mp->cease = cease;
9892   mp->is_no = is_no;
9893   mp->default_router = default_router;
9894
9895   /* send it... */
9896   S (mp);
9897
9898   /* Wait for a reply, return good/bad news  */
9899   W (ret);
9900   return ret;
9901 }
9902
9903 static int
9904 api_set_arp_neighbor_limit (vat_main_t * vam)
9905 {
9906   unformat_input_t *i = vam->input;
9907   vl_api_set_arp_neighbor_limit_t *mp;
9908   u32 arp_nbr_limit;
9909   u8 limit_set = 0;
9910   u8 is_ipv6 = 0;
9911   int ret;
9912
9913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9916         limit_set = 1;
9917       else if (unformat (i, "ipv6"))
9918         is_ipv6 = 1;
9919       else
9920         {
9921           clib_warning ("parse error '%U'", format_unformat_error, i);
9922           return -99;
9923         }
9924     }
9925
9926   if (limit_set == 0)
9927     {
9928       errmsg ("missing limit value");
9929       return -99;
9930     }
9931
9932   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9933
9934   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9935   mp->is_ipv6 = is_ipv6;
9936
9937   S (mp);
9938   W (ret);
9939   return ret;
9940 }
9941
9942 static int
9943 api_l2_patch_add_del (vat_main_t * vam)
9944 {
9945   unformat_input_t *i = vam->input;
9946   vl_api_l2_patch_add_del_t *mp;
9947   u32 rx_sw_if_index;
9948   u8 rx_sw_if_index_set = 0;
9949   u32 tx_sw_if_index;
9950   u8 tx_sw_if_index_set = 0;
9951   u8 is_add = 1;
9952   int ret;
9953
9954   /* Parse args required to build the message */
9955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9956     {
9957       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9958         rx_sw_if_index_set = 1;
9959       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9960         tx_sw_if_index_set = 1;
9961       else if (unformat (i, "rx"))
9962         {
9963           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964             {
9965               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9966                             &rx_sw_if_index))
9967                 rx_sw_if_index_set = 1;
9968             }
9969           else
9970             break;
9971         }
9972       else if (unformat (i, "tx"))
9973         {
9974           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9975             {
9976               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9977                             &tx_sw_if_index))
9978                 tx_sw_if_index_set = 1;
9979             }
9980           else
9981             break;
9982         }
9983       else if (unformat (i, "del"))
9984         is_add = 0;
9985       else
9986         break;
9987     }
9988
9989   if (rx_sw_if_index_set == 0)
9990     {
9991       errmsg ("missing rx interface name or rx_sw_if_index");
9992       return -99;
9993     }
9994
9995   if (tx_sw_if_index_set == 0)
9996     {
9997       errmsg ("missing tx interface name or tx_sw_if_index");
9998       return -99;
9999     }
10000
10001   M (L2_PATCH_ADD_DEL, mp);
10002
10003   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10004   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10005   mp->is_add = is_add;
10006
10007   S (mp);
10008   W (ret);
10009   return ret;
10010 }
10011
10012 u8 is_del;
10013 u8 localsid_addr[16];
10014 u8 end_psp;
10015 u8 behavior;
10016 u32 sw_if_index;
10017 u32 vlan_index;
10018 u32 fib_table;
10019 u8 nh_addr[16];
10020
10021 static int
10022 api_sr_localsid_add_del (vat_main_t * vam)
10023 {
10024   unformat_input_t *i = vam->input;
10025   vl_api_sr_localsid_add_del_t *mp;
10026
10027   u8 is_del;
10028   ip6_address_t localsid;
10029   u8 end_psp = 0;
10030   u8 behavior = ~0;
10031   u32 sw_if_index;
10032   u32 fib_table = ~(u32) 0;
10033   ip6_address_t next_hop;
10034
10035   bool nexthop_set = 0;
10036
10037   int ret;
10038
10039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10040     {
10041       if (unformat (i, "del"))
10042         is_del = 1;
10043       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10044       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10045         nexthop_set = 1;
10046       else if (unformat (i, "behavior %u", &behavior));
10047       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10048       else if (unformat (i, "fib-table %u", &fib_table));
10049       else if (unformat (i, "end.psp %u", &behavior));
10050       else
10051         break;
10052     }
10053
10054   M (SR_LOCALSID_ADD_DEL, mp);
10055
10056   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10057   if (nexthop_set)
10058     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10059   mp->behavior = behavior;
10060   mp->sw_if_index = ntohl (sw_if_index);
10061   mp->fib_table = ntohl (fib_table);
10062   mp->end_psp = end_psp;
10063   mp->is_del = is_del;
10064
10065   S (mp);
10066   W (ret);
10067   return ret;
10068 }
10069
10070 static int
10071 api_ioam_enable (vat_main_t * vam)
10072 {
10073   unformat_input_t *input = vam->input;
10074   vl_api_ioam_enable_t *mp;
10075   u32 id = 0;
10076   int has_trace_option = 0;
10077   int has_pot_option = 0;
10078   int has_seqno_option = 0;
10079   int has_analyse_option = 0;
10080   int ret;
10081
10082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10083     {
10084       if (unformat (input, "trace"))
10085         has_trace_option = 1;
10086       else if (unformat (input, "pot"))
10087         has_pot_option = 1;
10088       else if (unformat (input, "seqno"))
10089         has_seqno_option = 1;
10090       else if (unformat (input, "analyse"))
10091         has_analyse_option = 1;
10092       else
10093         break;
10094     }
10095   M (IOAM_ENABLE, mp);
10096   mp->id = htons (id);
10097   mp->seqno = has_seqno_option;
10098   mp->analyse = has_analyse_option;
10099   mp->pot_enable = has_pot_option;
10100   mp->trace_enable = has_trace_option;
10101
10102   S (mp);
10103   W (ret);
10104   return ret;
10105 }
10106
10107
10108 static int
10109 api_ioam_disable (vat_main_t * vam)
10110 {
10111   vl_api_ioam_disable_t *mp;
10112   int ret;
10113
10114   M (IOAM_DISABLE, mp);
10115   S (mp);
10116   W (ret);
10117   return ret;
10118 }
10119
10120 #define foreach_tcp_proto_field                 \
10121 _(src_port)                                     \
10122 _(dst_port)
10123
10124 #define foreach_udp_proto_field                 \
10125 _(src_port)                                     \
10126 _(dst_port)
10127
10128 #define foreach_ip4_proto_field                 \
10129 _(src_address)                                  \
10130 _(dst_address)                                  \
10131 _(tos)                                          \
10132 _(length)                                       \
10133 _(fragment_id)                                  \
10134 _(ttl)                                          \
10135 _(protocol)                                     \
10136 _(checksum)
10137
10138 typedef struct
10139 {
10140   u16 src_port, dst_port;
10141 } tcpudp_header_t;
10142
10143 #if VPP_API_TEST_BUILTIN == 0
10144 uword
10145 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10146 {
10147   u8 **maskp = va_arg (*args, u8 **);
10148   u8 *mask = 0;
10149   u8 found_something = 0;
10150   tcp_header_t *tcp;
10151
10152 #define _(a) u8 a=0;
10153   foreach_tcp_proto_field;
10154 #undef _
10155
10156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10157     {
10158       if (0);
10159 #define _(a) else if (unformat (input, #a)) a=1;
10160       foreach_tcp_proto_field
10161 #undef _
10162         else
10163         break;
10164     }
10165
10166 #define _(a) found_something += a;
10167   foreach_tcp_proto_field;
10168 #undef _
10169
10170   if (found_something == 0)
10171     return 0;
10172
10173   vec_validate (mask, sizeof (*tcp) - 1);
10174
10175   tcp = (tcp_header_t *) mask;
10176
10177 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10178   foreach_tcp_proto_field;
10179 #undef _
10180
10181   *maskp = mask;
10182   return 1;
10183 }
10184
10185 uword
10186 unformat_udp_mask (unformat_input_t * input, va_list * args)
10187 {
10188   u8 **maskp = va_arg (*args, u8 **);
10189   u8 *mask = 0;
10190   u8 found_something = 0;
10191   udp_header_t *udp;
10192
10193 #define _(a) u8 a=0;
10194   foreach_udp_proto_field;
10195 #undef _
10196
10197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10198     {
10199       if (0);
10200 #define _(a) else if (unformat (input, #a)) a=1;
10201       foreach_udp_proto_field
10202 #undef _
10203         else
10204         break;
10205     }
10206
10207 #define _(a) found_something += a;
10208   foreach_udp_proto_field;
10209 #undef _
10210
10211   if (found_something == 0)
10212     return 0;
10213
10214   vec_validate (mask, sizeof (*udp) - 1);
10215
10216   udp = (udp_header_t *) mask;
10217
10218 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10219   foreach_udp_proto_field;
10220 #undef _
10221
10222   *maskp = mask;
10223   return 1;
10224 }
10225
10226 uword
10227 unformat_l4_mask (unformat_input_t * input, va_list * args)
10228 {
10229   u8 **maskp = va_arg (*args, u8 **);
10230   u16 src_port = 0, dst_port = 0;
10231   tcpudp_header_t *tcpudp;
10232
10233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10236         return 1;
10237       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10238         return 1;
10239       else if (unformat (input, "src_port"))
10240         src_port = 0xFFFF;
10241       else if (unformat (input, "dst_port"))
10242         dst_port = 0xFFFF;
10243       else
10244         return 0;
10245     }
10246
10247   if (!src_port && !dst_port)
10248     return 0;
10249
10250   u8 *mask = 0;
10251   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10252
10253   tcpudp = (tcpudp_header_t *) mask;
10254   tcpudp->src_port = src_port;
10255   tcpudp->dst_port = dst_port;
10256
10257   *maskp = mask;
10258
10259   return 1;
10260 }
10261
10262 uword
10263 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10264 {
10265   u8 **maskp = va_arg (*args, u8 **);
10266   u8 *mask = 0;
10267   u8 found_something = 0;
10268   ip4_header_t *ip;
10269
10270 #define _(a) u8 a=0;
10271   foreach_ip4_proto_field;
10272 #undef _
10273   u8 version = 0;
10274   u8 hdr_length = 0;
10275
10276
10277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10278     {
10279       if (unformat (input, "version"))
10280         version = 1;
10281       else if (unformat (input, "hdr_length"))
10282         hdr_length = 1;
10283       else if (unformat (input, "src"))
10284         src_address = 1;
10285       else if (unformat (input, "dst"))
10286         dst_address = 1;
10287       else if (unformat (input, "proto"))
10288         protocol = 1;
10289
10290 #define _(a) else if (unformat (input, #a)) a=1;
10291       foreach_ip4_proto_field
10292 #undef _
10293         else
10294         break;
10295     }
10296
10297 #define _(a) found_something += a;
10298   foreach_ip4_proto_field;
10299 #undef _
10300
10301   if (found_something == 0)
10302     return 0;
10303
10304   vec_validate (mask, sizeof (*ip) - 1);
10305
10306   ip = (ip4_header_t *) mask;
10307
10308 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10309   foreach_ip4_proto_field;
10310 #undef _
10311
10312   ip->ip_version_and_header_length = 0;
10313
10314   if (version)
10315     ip->ip_version_and_header_length |= 0xF0;
10316
10317   if (hdr_length)
10318     ip->ip_version_and_header_length |= 0x0F;
10319
10320   *maskp = mask;
10321   return 1;
10322 }
10323
10324 #define foreach_ip6_proto_field                 \
10325 _(src_address)                                  \
10326 _(dst_address)                                  \
10327 _(payload_length)                               \
10328 _(hop_limit)                                    \
10329 _(protocol)
10330
10331 uword
10332 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10333 {
10334   u8 **maskp = va_arg (*args, u8 **);
10335   u8 *mask = 0;
10336   u8 found_something = 0;
10337   ip6_header_t *ip;
10338   u32 ip_version_traffic_class_and_flow_label;
10339
10340 #define _(a) u8 a=0;
10341   foreach_ip6_proto_field;
10342 #undef _
10343   u8 version = 0;
10344   u8 traffic_class = 0;
10345   u8 flow_label = 0;
10346
10347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10348     {
10349       if (unformat (input, "version"))
10350         version = 1;
10351       else if (unformat (input, "traffic-class"))
10352         traffic_class = 1;
10353       else if (unformat (input, "flow-label"))
10354         flow_label = 1;
10355       else if (unformat (input, "src"))
10356         src_address = 1;
10357       else if (unformat (input, "dst"))
10358         dst_address = 1;
10359       else if (unformat (input, "proto"))
10360         protocol = 1;
10361
10362 #define _(a) else if (unformat (input, #a)) a=1;
10363       foreach_ip6_proto_field
10364 #undef _
10365         else
10366         break;
10367     }
10368
10369 #define _(a) found_something += a;
10370   foreach_ip6_proto_field;
10371 #undef _
10372
10373   if (found_something == 0)
10374     return 0;
10375
10376   vec_validate (mask, sizeof (*ip) - 1);
10377
10378   ip = (ip6_header_t *) mask;
10379
10380 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10381   foreach_ip6_proto_field;
10382 #undef _
10383
10384   ip_version_traffic_class_and_flow_label = 0;
10385
10386   if (version)
10387     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10388
10389   if (traffic_class)
10390     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10391
10392   if (flow_label)
10393     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10394
10395   ip->ip_version_traffic_class_and_flow_label =
10396     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10397
10398   *maskp = mask;
10399   return 1;
10400 }
10401
10402 uword
10403 unformat_l3_mask (unformat_input_t * input, va_list * args)
10404 {
10405   u8 **maskp = va_arg (*args, u8 **);
10406
10407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10408     {
10409       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10410         return 1;
10411       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10412         return 1;
10413       else
10414         break;
10415     }
10416   return 0;
10417 }
10418
10419 uword
10420 unformat_l2_mask (unformat_input_t * input, va_list * args)
10421 {
10422   u8 **maskp = va_arg (*args, u8 **);
10423   u8 *mask = 0;
10424   u8 src = 0;
10425   u8 dst = 0;
10426   u8 proto = 0;
10427   u8 tag1 = 0;
10428   u8 tag2 = 0;
10429   u8 ignore_tag1 = 0;
10430   u8 ignore_tag2 = 0;
10431   u8 cos1 = 0;
10432   u8 cos2 = 0;
10433   u8 dot1q = 0;
10434   u8 dot1ad = 0;
10435   int len = 14;
10436
10437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10438     {
10439       if (unformat (input, "src"))
10440         src = 1;
10441       else if (unformat (input, "dst"))
10442         dst = 1;
10443       else if (unformat (input, "proto"))
10444         proto = 1;
10445       else if (unformat (input, "tag1"))
10446         tag1 = 1;
10447       else if (unformat (input, "tag2"))
10448         tag2 = 1;
10449       else if (unformat (input, "ignore-tag1"))
10450         ignore_tag1 = 1;
10451       else if (unformat (input, "ignore-tag2"))
10452         ignore_tag2 = 1;
10453       else if (unformat (input, "cos1"))
10454         cos1 = 1;
10455       else if (unformat (input, "cos2"))
10456         cos2 = 1;
10457       else if (unformat (input, "dot1q"))
10458         dot1q = 1;
10459       else if (unformat (input, "dot1ad"))
10460         dot1ad = 1;
10461       else
10462         break;
10463     }
10464   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10465        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10466     return 0;
10467
10468   if (tag1 || ignore_tag1 || cos1 || dot1q)
10469     len = 18;
10470   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10471     len = 22;
10472
10473   vec_validate (mask, len - 1);
10474
10475   if (dst)
10476     memset (mask, 0xff, 6);
10477
10478   if (src)
10479     memset (mask + 6, 0xff, 6);
10480
10481   if (tag2 || dot1ad)
10482     {
10483       /* inner vlan tag */
10484       if (tag2)
10485         {
10486           mask[19] = 0xff;
10487           mask[18] = 0x0f;
10488         }
10489       if (cos2)
10490         mask[18] |= 0xe0;
10491       if (proto)
10492         mask[21] = mask[20] = 0xff;
10493       if (tag1)
10494         {
10495           mask[15] = 0xff;
10496           mask[14] = 0x0f;
10497         }
10498       if (cos1)
10499         mask[14] |= 0xe0;
10500       *maskp = mask;
10501       return 1;
10502     }
10503   if (tag1 | dot1q)
10504     {
10505       if (tag1)
10506         {
10507           mask[15] = 0xff;
10508           mask[14] = 0x0f;
10509         }
10510       if (cos1)
10511         mask[14] |= 0xe0;
10512       if (proto)
10513         mask[16] = mask[17] = 0xff;
10514
10515       *maskp = mask;
10516       return 1;
10517     }
10518   if (cos2)
10519     mask[18] |= 0xe0;
10520   if (cos1)
10521     mask[14] |= 0xe0;
10522   if (proto)
10523     mask[12] = mask[13] = 0xff;
10524
10525   *maskp = mask;
10526   return 1;
10527 }
10528
10529 uword
10530 unformat_classify_mask (unformat_input_t * input, va_list * args)
10531 {
10532   u8 **maskp = va_arg (*args, u8 **);
10533   u32 *skipp = va_arg (*args, u32 *);
10534   u32 *matchp = va_arg (*args, u32 *);
10535   u32 match;
10536   u8 *mask = 0;
10537   u8 *l2 = 0;
10538   u8 *l3 = 0;
10539   u8 *l4 = 0;
10540   int i;
10541
10542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10543     {
10544       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10545         ;
10546       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10547         ;
10548       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10549         ;
10550       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10551         ;
10552       else
10553         break;
10554     }
10555
10556   if (l4 && !l3)
10557     {
10558       vec_free (mask);
10559       vec_free (l2);
10560       vec_free (l4);
10561       return 0;
10562     }
10563
10564   if (mask || l2 || l3 || l4)
10565     {
10566       if (l2 || l3 || l4)
10567         {
10568           /* "With a free Ethernet header in every package" */
10569           if (l2 == 0)
10570             vec_validate (l2, 13);
10571           mask = l2;
10572           if (vec_len (l3))
10573             {
10574               vec_append (mask, l3);
10575               vec_free (l3);
10576             }
10577           if (vec_len (l4))
10578             {
10579               vec_append (mask, l4);
10580               vec_free (l4);
10581             }
10582         }
10583
10584       /* Scan forward looking for the first significant mask octet */
10585       for (i = 0; i < vec_len (mask); i++)
10586         if (mask[i])
10587           break;
10588
10589       /* compute (skip, match) params */
10590       *skipp = i / sizeof (u32x4);
10591       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10592
10593       /* Pad mask to an even multiple of the vector size */
10594       while (vec_len (mask) % sizeof (u32x4))
10595         vec_add1 (mask, 0);
10596
10597       match = vec_len (mask) / sizeof (u32x4);
10598
10599       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10600         {
10601           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10602           if (*tmp || *(tmp + 1))
10603             break;
10604           match--;
10605         }
10606       if (match == 0)
10607         clib_warning ("BUG: match 0");
10608
10609       _vec_len (mask) = match * sizeof (u32x4);
10610
10611       *matchp = match;
10612       *maskp = mask;
10613
10614       return 1;
10615     }
10616
10617   return 0;
10618 }
10619 #endif /* VPP_API_TEST_BUILTIN */
10620
10621 #define foreach_l2_next                         \
10622 _(drop, DROP)                                   \
10623 _(ethernet, ETHERNET_INPUT)                     \
10624 _(ip4, IP4_INPUT)                               \
10625 _(ip6, IP6_INPUT)
10626
10627 uword
10628 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10629 {
10630   u32 *miss_next_indexp = va_arg (*args, u32 *);
10631   u32 next_index = 0;
10632   u32 tmp;
10633
10634 #define _(n,N) \
10635   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10636   foreach_l2_next;
10637 #undef _
10638
10639   if (unformat (input, "%d", &tmp))
10640     {
10641       next_index = tmp;
10642       goto out;
10643     }
10644
10645   return 0;
10646
10647 out:
10648   *miss_next_indexp = next_index;
10649   return 1;
10650 }
10651
10652 #define foreach_ip_next                         \
10653 _(drop, DROP)                                   \
10654 _(local, LOCAL)                                 \
10655 _(rewrite, REWRITE)
10656
10657 uword
10658 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10659 {
10660   u32 *miss_next_indexp = va_arg (*args, u32 *);
10661   u32 next_index = 0;
10662   u32 tmp;
10663
10664 #define _(n,N) \
10665   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10666   foreach_ip_next;
10667 #undef _
10668
10669   if (unformat (input, "%d", &tmp))
10670     {
10671       next_index = tmp;
10672       goto out;
10673     }
10674
10675   return 0;
10676
10677 out:
10678   *miss_next_indexp = next_index;
10679   return 1;
10680 }
10681
10682 #define foreach_acl_next                        \
10683 _(deny, DENY)
10684
10685 uword
10686 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10687 {
10688   u32 *miss_next_indexp = va_arg (*args, u32 *);
10689   u32 next_index = 0;
10690   u32 tmp;
10691
10692 #define _(n,N) \
10693   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10694   foreach_acl_next;
10695 #undef _
10696
10697   if (unformat (input, "permit"))
10698     {
10699       next_index = ~0;
10700       goto out;
10701     }
10702   else if (unformat (input, "%d", &tmp))
10703     {
10704       next_index = tmp;
10705       goto out;
10706     }
10707
10708   return 0;
10709
10710 out:
10711   *miss_next_indexp = next_index;
10712   return 1;
10713 }
10714
10715 uword
10716 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10717 {
10718   u32 *r = va_arg (*args, u32 *);
10719
10720   if (unformat (input, "conform-color"))
10721     *r = POLICE_CONFORM;
10722   else if (unformat (input, "exceed-color"))
10723     *r = POLICE_EXCEED;
10724   else
10725     return 0;
10726
10727   return 1;
10728 }
10729
10730 static int
10731 api_classify_add_del_table (vat_main_t * vam)
10732 {
10733   unformat_input_t *i = vam->input;
10734   vl_api_classify_add_del_table_t *mp;
10735
10736   u32 nbuckets = 2;
10737   u32 skip = ~0;
10738   u32 match = ~0;
10739   int is_add = 1;
10740   int del_chain = 0;
10741   u32 table_index = ~0;
10742   u32 next_table_index = ~0;
10743   u32 miss_next_index = ~0;
10744   u32 memory_size = 32 << 20;
10745   u8 *mask = 0;
10746   u32 current_data_flag = 0;
10747   int current_data_offset = 0;
10748   int ret;
10749
10750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10751     {
10752       if (unformat (i, "del"))
10753         is_add = 0;
10754       else if (unformat (i, "del-chain"))
10755         {
10756           is_add = 0;
10757           del_chain = 1;
10758         }
10759       else if (unformat (i, "buckets %d", &nbuckets))
10760         ;
10761       else if (unformat (i, "memory_size %d", &memory_size))
10762         ;
10763       else if (unformat (i, "skip %d", &skip))
10764         ;
10765       else if (unformat (i, "match %d", &match))
10766         ;
10767       else if (unformat (i, "table %d", &table_index))
10768         ;
10769       else if (unformat (i, "mask %U", unformat_classify_mask,
10770                          &mask, &skip, &match))
10771         ;
10772       else if (unformat (i, "next-table %d", &next_table_index))
10773         ;
10774       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10775                          &miss_next_index))
10776         ;
10777       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10778                          &miss_next_index))
10779         ;
10780       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10781                          &miss_next_index))
10782         ;
10783       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10784         ;
10785       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10786         ;
10787       else
10788         break;
10789     }
10790
10791   if (is_add && mask == 0)
10792     {
10793       errmsg ("Mask required");
10794       return -99;
10795     }
10796
10797   if (is_add && skip == ~0)
10798     {
10799       errmsg ("skip count required");
10800       return -99;
10801     }
10802
10803   if (is_add && match == ~0)
10804     {
10805       errmsg ("match count required");
10806       return -99;
10807     }
10808
10809   if (!is_add && table_index == ~0)
10810     {
10811       errmsg ("table index required for delete");
10812       return -99;
10813     }
10814
10815   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10816
10817   mp->is_add = is_add;
10818   mp->del_chain = del_chain;
10819   mp->table_index = ntohl (table_index);
10820   mp->nbuckets = ntohl (nbuckets);
10821   mp->memory_size = ntohl (memory_size);
10822   mp->skip_n_vectors = ntohl (skip);
10823   mp->match_n_vectors = ntohl (match);
10824   mp->next_table_index = ntohl (next_table_index);
10825   mp->miss_next_index = ntohl (miss_next_index);
10826   mp->current_data_flag = ntohl (current_data_flag);
10827   mp->current_data_offset = ntohl (current_data_offset);
10828   clib_memcpy (mp->mask, mask, vec_len (mask));
10829
10830   vec_free (mask);
10831
10832   S (mp);
10833   W (ret);
10834   return ret;
10835 }
10836
10837 #if VPP_API_TEST_BUILTIN == 0
10838 uword
10839 unformat_l4_match (unformat_input_t * input, va_list * args)
10840 {
10841   u8 **matchp = va_arg (*args, u8 **);
10842
10843   u8 *proto_header = 0;
10844   int src_port = 0;
10845   int dst_port = 0;
10846
10847   tcpudp_header_t h;
10848
10849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10850     {
10851       if (unformat (input, "src_port %d", &src_port))
10852         ;
10853       else if (unformat (input, "dst_port %d", &dst_port))
10854         ;
10855       else
10856         return 0;
10857     }
10858
10859   h.src_port = clib_host_to_net_u16 (src_port);
10860   h.dst_port = clib_host_to_net_u16 (dst_port);
10861   vec_validate (proto_header, sizeof (h) - 1);
10862   memcpy (proto_header, &h, sizeof (h));
10863
10864   *matchp = proto_header;
10865
10866   return 1;
10867 }
10868
10869 uword
10870 unformat_ip4_match (unformat_input_t * input, va_list * args)
10871 {
10872   u8 **matchp = va_arg (*args, u8 **);
10873   u8 *match = 0;
10874   ip4_header_t *ip;
10875   int version = 0;
10876   u32 version_val;
10877   int hdr_length = 0;
10878   u32 hdr_length_val;
10879   int src = 0, dst = 0;
10880   ip4_address_t src_val, dst_val;
10881   int proto = 0;
10882   u32 proto_val;
10883   int tos = 0;
10884   u32 tos_val;
10885   int length = 0;
10886   u32 length_val;
10887   int fragment_id = 0;
10888   u32 fragment_id_val;
10889   int ttl = 0;
10890   int ttl_val;
10891   int checksum = 0;
10892   u32 checksum_val;
10893
10894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (input, "version %d", &version_val))
10897         version = 1;
10898       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10899         hdr_length = 1;
10900       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10901         src = 1;
10902       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10903         dst = 1;
10904       else if (unformat (input, "proto %d", &proto_val))
10905         proto = 1;
10906       else if (unformat (input, "tos %d", &tos_val))
10907         tos = 1;
10908       else if (unformat (input, "length %d", &length_val))
10909         length = 1;
10910       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10911         fragment_id = 1;
10912       else if (unformat (input, "ttl %d", &ttl_val))
10913         ttl = 1;
10914       else if (unformat (input, "checksum %d", &checksum_val))
10915         checksum = 1;
10916       else
10917         break;
10918     }
10919
10920   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10921       + ttl + checksum == 0)
10922     return 0;
10923
10924   /*
10925    * Aligned because we use the real comparison functions
10926    */
10927   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10928
10929   ip = (ip4_header_t *) match;
10930
10931   /* These are realistically matched in practice */
10932   if (src)
10933     ip->src_address.as_u32 = src_val.as_u32;
10934
10935   if (dst)
10936     ip->dst_address.as_u32 = dst_val.as_u32;
10937
10938   if (proto)
10939     ip->protocol = proto_val;
10940
10941
10942   /* These are not, but they're included for completeness */
10943   if (version)
10944     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10945
10946   if (hdr_length)
10947     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10948
10949   if (tos)
10950     ip->tos = tos_val;
10951
10952   if (length)
10953     ip->length = clib_host_to_net_u16 (length_val);
10954
10955   if (ttl)
10956     ip->ttl = ttl_val;
10957
10958   if (checksum)
10959     ip->checksum = clib_host_to_net_u16 (checksum_val);
10960
10961   *matchp = match;
10962   return 1;
10963 }
10964
10965 uword
10966 unformat_ip6_match (unformat_input_t * input, va_list * args)
10967 {
10968   u8 **matchp = va_arg (*args, u8 **);
10969   u8 *match = 0;
10970   ip6_header_t *ip;
10971   int version = 0;
10972   u32 version_val;
10973   u8 traffic_class = 0;
10974   u32 traffic_class_val = 0;
10975   u8 flow_label = 0;
10976   u8 flow_label_val;
10977   int src = 0, dst = 0;
10978   ip6_address_t src_val, dst_val;
10979   int proto = 0;
10980   u32 proto_val;
10981   int payload_length = 0;
10982   u32 payload_length_val;
10983   int hop_limit = 0;
10984   int hop_limit_val;
10985   u32 ip_version_traffic_class_and_flow_label;
10986
10987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10988     {
10989       if (unformat (input, "version %d", &version_val))
10990         version = 1;
10991       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10992         traffic_class = 1;
10993       else if (unformat (input, "flow_label %d", &flow_label_val))
10994         flow_label = 1;
10995       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10996         src = 1;
10997       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10998         dst = 1;
10999       else if (unformat (input, "proto %d", &proto_val))
11000         proto = 1;
11001       else if (unformat (input, "payload_length %d", &payload_length_val))
11002         payload_length = 1;
11003       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11004         hop_limit = 1;
11005       else
11006         break;
11007     }
11008
11009   if (version + traffic_class + flow_label + src + dst + proto +
11010       payload_length + hop_limit == 0)
11011     return 0;
11012
11013   /*
11014    * Aligned because we use the real comparison functions
11015    */
11016   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11017
11018   ip = (ip6_header_t *) match;
11019
11020   if (src)
11021     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11022
11023   if (dst)
11024     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11025
11026   if (proto)
11027     ip->protocol = proto_val;
11028
11029   ip_version_traffic_class_and_flow_label = 0;
11030
11031   if (version)
11032     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11033
11034   if (traffic_class)
11035     ip_version_traffic_class_and_flow_label |=
11036       (traffic_class_val & 0xFF) << 20;
11037
11038   if (flow_label)
11039     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11040
11041   ip->ip_version_traffic_class_and_flow_label =
11042     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11043
11044   if (payload_length)
11045     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11046
11047   if (hop_limit)
11048     ip->hop_limit = hop_limit_val;
11049
11050   *matchp = match;
11051   return 1;
11052 }
11053
11054 uword
11055 unformat_l3_match (unformat_input_t * input, va_list * args)
11056 {
11057   u8 **matchp = va_arg (*args, u8 **);
11058
11059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11062         return 1;
11063       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11064         return 1;
11065       else
11066         break;
11067     }
11068   return 0;
11069 }
11070
11071 uword
11072 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11073 {
11074   u8 *tagp = va_arg (*args, u8 *);
11075   u32 tag;
11076
11077   if (unformat (input, "%d", &tag))
11078     {
11079       tagp[0] = (tag >> 8) & 0x0F;
11080       tagp[1] = tag & 0xFF;
11081       return 1;
11082     }
11083
11084   return 0;
11085 }
11086
11087 uword
11088 unformat_l2_match (unformat_input_t * input, va_list * args)
11089 {
11090   u8 **matchp = va_arg (*args, u8 **);
11091   u8 *match = 0;
11092   u8 src = 0;
11093   u8 src_val[6];
11094   u8 dst = 0;
11095   u8 dst_val[6];
11096   u8 proto = 0;
11097   u16 proto_val;
11098   u8 tag1 = 0;
11099   u8 tag1_val[2];
11100   u8 tag2 = 0;
11101   u8 tag2_val[2];
11102   int len = 14;
11103   u8 ignore_tag1 = 0;
11104   u8 ignore_tag2 = 0;
11105   u8 cos1 = 0;
11106   u8 cos2 = 0;
11107   u32 cos1_val = 0;
11108   u32 cos2_val = 0;
11109
11110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11111     {
11112       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11113         src = 1;
11114       else
11115         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11116         dst = 1;
11117       else if (unformat (input, "proto %U",
11118                          unformat_ethernet_type_host_byte_order, &proto_val))
11119         proto = 1;
11120       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11121         tag1 = 1;
11122       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11123         tag2 = 1;
11124       else if (unformat (input, "ignore-tag1"))
11125         ignore_tag1 = 1;
11126       else if (unformat (input, "ignore-tag2"))
11127         ignore_tag2 = 1;
11128       else if (unformat (input, "cos1 %d", &cos1_val))
11129         cos1 = 1;
11130       else if (unformat (input, "cos2 %d", &cos2_val))
11131         cos2 = 1;
11132       else
11133         break;
11134     }
11135   if ((src + dst + proto + tag1 + tag2 +
11136        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11137     return 0;
11138
11139   if (tag1 || ignore_tag1 || cos1)
11140     len = 18;
11141   if (tag2 || ignore_tag2 || cos2)
11142     len = 22;
11143
11144   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11145
11146   if (dst)
11147     clib_memcpy (match, dst_val, 6);
11148
11149   if (src)
11150     clib_memcpy (match + 6, src_val, 6);
11151
11152   if (tag2)
11153     {
11154       /* inner vlan tag */
11155       match[19] = tag2_val[1];
11156       match[18] = tag2_val[0];
11157       if (cos2)
11158         match[18] |= (cos2_val & 0x7) << 5;
11159       if (proto)
11160         {
11161           match[21] = proto_val & 0xff;
11162           match[20] = proto_val >> 8;
11163         }
11164       if (tag1)
11165         {
11166           match[15] = tag1_val[1];
11167           match[14] = tag1_val[0];
11168         }
11169       if (cos1)
11170         match[14] |= (cos1_val & 0x7) << 5;
11171       *matchp = match;
11172       return 1;
11173     }
11174   if (tag1)
11175     {
11176       match[15] = tag1_val[1];
11177       match[14] = tag1_val[0];
11178       if (proto)
11179         {
11180           match[17] = proto_val & 0xff;
11181           match[16] = proto_val >> 8;
11182         }
11183       if (cos1)
11184         match[14] |= (cos1_val & 0x7) << 5;
11185
11186       *matchp = match;
11187       return 1;
11188     }
11189   if (cos2)
11190     match[18] |= (cos2_val & 0x7) << 5;
11191   if (cos1)
11192     match[14] |= (cos1_val & 0x7) << 5;
11193   if (proto)
11194     {
11195       match[13] = proto_val & 0xff;
11196       match[12] = proto_val >> 8;
11197     }
11198
11199   *matchp = match;
11200   return 1;
11201 }
11202 #endif
11203
11204 uword
11205 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11206 {
11207   u8 **matchp = va_arg (*args, u8 **);
11208   u32 skip_n_vectors = va_arg (*args, u32);
11209   u32 match_n_vectors = va_arg (*args, u32);
11210
11211   u8 *match = 0;
11212   u8 *l2 = 0;
11213   u8 *l3 = 0;
11214   u8 *l4 = 0;
11215
11216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11217     {
11218       if (unformat (input, "hex %U", unformat_hex_string, &match))
11219         ;
11220       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11221         ;
11222       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11223         ;
11224       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11225         ;
11226       else
11227         break;
11228     }
11229
11230   if (l4 && !l3)
11231     {
11232       vec_free (match);
11233       vec_free (l2);
11234       vec_free (l4);
11235       return 0;
11236     }
11237
11238   if (match || l2 || l3 || l4)
11239     {
11240       if (l2 || l3 || l4)
11241         {
11242           /* "Win a free Ethernet header in every packet" */
11243           if (l2 == 0)
11244             vec_validate_aligned (l2, 13, sizeof (u32x4));
11245           match = l2;
11246           if (vec_len (l3))
11247             {
11248               vec_append_aligned (match, l3, sizeof (u32x4));
11249               vec_free (l3);
11250             }
11251           if (vec_len (l4))
11252             {
11253               vec_append_aligned (match, l4, sizeof (u32x4));
11254               vec_free (l4);
11255             }
11256         }
11257
11258       /* Make sure the vector is big enough even if key is all 0's */
11259       vec_validate_aligned
11260         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11261          sizeof (u32x4));
11262
11263       /* Set size, include skipped vectors */
11264       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11265
11266       *matchp = match;
11267
11268       return 1;
11269     }
11270
11271   return 0;
11272 }
11273
11274 static int
11275 api_classify_add_del_session (vat_main_t * vam)
11276 {
11277   unformat_input_t *i = vam->input;
11278   vl_api_classify_add_del_session_t *mp;
11279   int is_add = 1;
11280   u32 table_index = ~0;
11281   u32 hit_next_index = ~0;
11282   u32 opaque_index = ~0;
11283   u8 *match = 0;
11284   i32 advance = 0;
11285   u32 skip_n_vectors = 0;
11286   u32 match_n_vectors = 0;
11287   u32 action = 0;
11288   u32 metadata = 0;
11289   int ret;
11290
11291   /*
11292    * Warning: you have to supply skip_n and match_n
11293    * because the API client cant simply look at the classify
11294    * table object.
11295    */
11296
11297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (i, "del"))
11300         is_add = 0;
11301       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11302                          &hit_next_index))
11303         ;
11304       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11305                          &hit_next_index))
11306         ;
11307       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11308                          &hit_next_index))
11309         ;
11310       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11311         ;
11312       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11313         ;
11314       else if (unformat (i, "opaque-index %d", &opaque_index))
11315         ;
11316       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11317         ;
11318       else if (unformat (i, "match_n %d", &match_n_vectors))
11319         ;
11320       else if (unformat (i, "match %U", api_unformat_classify_match,
11321                          &match, skip_n_vectors, match_n_vectors))
11322         ;
11323       else if (unformat (i, "advance %d", &advance))
11324         ;
11325       else if (unformat (i, "table-index %d", &table_index))
11326         ;
11327       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11328         action = 1;
11329       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11330         action = 2;
11331       else if (unformat (i, "action %d", &action))
11332         ;
11333       else if (unformat (i, "metadata %d", &metadata))
11334         ;
11335       else
11336         break;
11337     }
11338
11339   if (table_index == ~0)
11340     {
11341       errmsg ("Table index required");
11342       return -99;
11343     }
11344
11345   if (is_add && match == 0)
11346     {
11347       errmsg ("Match value required");
11348       return -99;
11349     }
11350
11351   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11352
11353   mp->is_add = is_add;
11354   mp->table_index = ntohl (table_index);
11355   mp->hit_next_index = ntohl (hit_next_index);
11356   mp->opaque_index = ntohl (opaque_index);
11357   mp->advance = ntohl (advance);
11358   mp->action = action;
11359   mp->metadata = ntohl (metadata);
11360   clib_memcpy (mp->match, match, vec_len (match));
11361   vec_free (match);
11362
11363   S (mp);
11364   W (ret);
11365   return ret;
11366 }
11367
11368 static int
11369 api_classify_set_interface_ip_table (vat_main_t * vam)
11370 {
11371   unformat_input_t *i = vam->input;
11372   vl_api_classify_set_interface_ip_table_t *mp;
11373   u32 sw_if_index;
11374   int sw_if_index_set;
11375   u32 table_index = ~0;
11376   u8 is_ipv6 = 0;
11377   int ret;
11378
11379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11380     {
11381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11382         sw_if_index_set = 1;
11383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11384         sw_if_index_set = 1;
11385       else if (unformat (i, "table %d", &table_index))
11386         ;
11387       else
11388         {
11389           clib_warning ("parse error '%U'", format_unformat_error, i);
11390           return -99;
11391         }
11392     }
11393
11394   if (sw_if_index_set == 0)
11395     {
11396       errmsg ("missing interface name or sw_if_index");
11397       return -99;
11398     }
11399
11400
11401   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11402
11403   mp->sw_if_index = ntohl (sw_if_index);
11404   mp->table_index = ntohl (table_index);
11405   mp->is_ipv6 = is_ipv6;
11406
11407   S (mp);
11408   W (ret);
11409   return ret;
11410 }
11411
11412 static int
11413 api_classify_set_interface_l2_tables (vat_main_t * vam)
11414 {
11415   unformat_input_t *i = vam->input;
11416   vl_api_classify_set_interface_l2_tables_t *mp;
11417   u32 sw_if_index;
11418   int sw_if_index_set;
11419   u32 ip4_table_index = ~0;
11420   u32 ip6_table_index = ~0;
11421   u32 other_table_index = ~0;
11422   u32 is_input = 1;
11423   int ret;
11424
11425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11426     {
11427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11428         sw_if_index_set = 1;
11429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11430         sw_if_index_set = 1;
11431       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11432         ;
11433       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11434         ;
11435       else if (unformat (i, "other-table %d", &other_table_index))
11436         ;
11437       else if (unformat (i, "is-input %d", &is_input))
11438         ;
11439       else
11440         {
11441           clib_warning ("parse error '%U'", format_unformat_error, i);
11442           return -99;
11443         }
11444     }
11445
11446   if (sw_if_index_set == 0)
11447     {
11448       errmsg ("missing interface name or sw_if_index");
11449       return -99;
11450     }
11451
11452
11453   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11454
11455   mp->sw_if_index = ntohl (sw_if_index);
11456   mp->ip4_table_index = ntohl (ip4_table_index);
11457   mp->ip6_table_index = ntohl (ip6_table_index);
11458   mp->other_table_index = ntohl (other_table_index);
11459   mp->is_input = (u8) is_input;
11460
11461   S (mp);
11462   W (ret);
11463   return ret;
11464 }
11465
11466 static int
11467 api_set_ipfix_exporter (vat_main_t * vam)
11468 {
11469   unformat_input_t *i = vam->input;
11470   vl_api_set_ipfix_exporter_t *mp;
11471   ip4_address_t collector_address;
11472   u8 collector_address_set = 0;
11473   u32 collector_port = ~0;
11474   ip4_address_t src_address;
11475   u8 src_address_set = 0;
11476   u32 vrf_id = ~0;
11477   u32 path_mtu = ~0;
11478   u32 template_interval = ~0;
11479   u8 udp_checksum = 0;
11480   int ret;
11481
11482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (i, "collector_address %U", unformat_ip4_address,
11485                     &collector_address))
11486         collector_address_set = 1;
11487       else if (unformat (i, "collector_port %d", &collector_port))
11488         ;
11489       else if (unformat (i, "src_address %U", unformat_ip4_address,
11490                          &src_address))
11491         src_address_set = 1;
11492       else if (unformat (i, "vrf_id %d", &vrf_id))
11493         ;
11494       else if (unformat (i, "path_mtu %d", &path_mtu))
11495         ;
11496       else if (unformat (i, "template_interval %d", &template_interval))
11497         ;
11498       else if (unformat (i, "udp_checksum"))
11499         udp_checksum = 1;
11500       else
11501         break;
11502     }
11503
11504   if (collector_address_set == 0)
11505     {
11506       errmsg ("collector_address required");
11507       return -99;
11508     }
11509
11510   if (src_address_set == 0)
11511     {
11512       errmsg ("src_address required");
11513       return -99;
11514     }
11515
11516   M (SET_IPFIX_EXPORTER, mp);
11517
11518   memcpy (mp->collector_address, collector_address.data,
11519           sizeof (collector_address.data));
11520   mp->collector_port = htons ((u16) collector_port);
11521   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11522   mp->vrf_id = htonl (vrf_id);
11523   mp->path_mtu = htonl (path_mtu);
11524   mp->template_interval = htonl (template_interval);
11525   mp->udp_checksum = udp_checksum;
11526
11527   S (mp);
11528   W (ret);
11529   return ret;
11530 }
11531
11532 static int
11533 api_set_ipfix_classify_stream (vat_main_t * vam)
11534 {
11535   unformat_input_t *i = vam->input;
11536   vl_api_set_ipfix_classify_stream_t *mp;
11537   u32 domain_id = 0;
11538   u32 src_port = UDP_DST_PORT_ipfix;
11539   int ret;
11540
11541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (i, "domain %d", &domain_id))
11544         ;
11545       else if (unformat (i, "src_port %d", &src_port))
11546         ;
11547       else
11548         {
11549           errmsg ("unknown input `%U'", format_unformat_error, i);
11550           return -99;
11551         }
11552     }
11553
11554   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11555
11556   mp->domain_id = htonl (domain_id);
11557   mp->src_port = htons ((u16) src_port);
11558
11559   S (mp);
11560   W (ret);
11561   return ret;
11562 }
11563
11564 static int
11565 api_ipfix_classify_table_add_del (vat_main_t * vam)
11566 {
11567   unformat_input_t *i = vam->input;
11568   vl_api_ipfix_classify_table_add_del_t *mp;
11569   int is_add = -1;
11570   u32 classify_table_index = ~0;
11571   u8 ip_version = 0;
11572   u8 transport_protocol = 255;
11573   int ret;
11574
11575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11576     {
11577       if (unformat (i, "add"))
11578         is_add = 1;
11579       else if (unformat (i, "del"))
11580         is_add = 0;
11581       else if (unformat (i, "table %d", &classify_table_index))
11582         ;
11583       else if (unformat (i, "ip4"))
11584         ip_version = 4;
11585       else if (unformat (i, "ip6"))
11586         ip_version = 6;
11587       else if (unformat (i, "tcp"))
11588         transport_protocol = 6;
11589       else if (unformat (i, "udp"))
11590         transport_protocol = 17;
11591       else
11592         {
11593           errmsg ("unknown input `%U'", format_unformat_error, i);
11594           return -99;
11595         }
11596     }
11597
11598   if (is_add == -1)
11599     {
11600       errmsg ("expecting: add|del");
11601       return -99;
11602     }
11603   if (classify_table_index == ~0)
11604     {
11605       errmsg ("classifier table not specified");
11606       return -99;
11607     }
11608   if (ip_version == 0)
11609     {
11610       errmsg ("IP version not specified");
11611       return -99;
11612     }
11613
11614   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11615
11616   mp->is_add = is_add;
11617   mp->table_id = htonl (classify_table_index);
11618   mp->ip_version = ip_version;
11619   mp->transport_protocol = transport_protocol;
11620
11621   S (mp);
11622   W (ret);
11623   return ret;
11624 }
11625
11626 static int
11627 api_get_node_index (vat_main_t * vam)
11628 {
11629   unformat_input_t *i = vam->input;
11630   vl_api_get_node_index_t *mp;
11631   u8 *name = 0;
11632   int ret;
11633
11634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11635     {
11636       if (unformat (i, "node %s", &name))
11637         ;
11638       else
11639         break;
11640     }
11641   if (name == 0)
11642     {
11643       errmsg ("node name required");
11644       return -99;
11645     }
11646   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11647     {
11648       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11649       return -99;
11650     }
11651
11652   M (GET_NODE_INDEX, mp);
11653   clib_memcpy (mp->node_name, name, vec_len (name));
11654   vec_free (name);
11655
11656   S (mp);
11657   W (ret);
11658   return ret;
11659 }
11660
11661 static int
11662 api_get_next_index (vat_main_t * vam)
11663 {
11664   unformat_input_t *i = vam->input;
11665   vl_api_get_next_index_t *mp;
11666   u8 *node_name = 0, *next_node_name = 0;
11667   int ret;
11668
11669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11670     {
11671       if (unformat (i, "node-name %s", &node_name))
11672         ;
11673       else if (unformat (i, "next-node-name %s", &next_node_name))
11674         break;
11675     }
11676
11677   if (node_name == 0)
11678     {
11679       errmsg ("node name required");
11680       return -99;
11681     }
11682   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11683     {
11684       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11685       return -99;
11686     }
11687
11688   if (next_node_name == 0)
11689     {
11690       errmsg ("next node name required");
11691       return -99;
11692     }
11693   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11694     {
11695       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11696       return -99;
11697     }
11698
11699   M (GET_NEXT_INDEX, mp);
11700   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11701   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11702   vec_free (node_name);
11703   vec_free (next_node_name);
11704
11705   S (mp);
11706   W (ret);
11707   return ret;
11708 }
11709
11710 static int
11711 api_add_node_next (vat_main_t * vam)
11712 {
11713   unformat_input_t *i = vam->input;
11714   vl_api_add_node_next_t *mp;
11715   u8 *name = 0;
11716   u8 *next = 0;
11717   int ret;
11718
11719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11720     {
11721       if (unformat (i, "node %s", &name))
11722         ;
11723       else if (unformat (i, "next %s", &next))
11724         ;
11725       else
11726         break;
11727     }
11728   if (name == 0)
11729     {
11730       errmsg ("node name required");
11731       return -99;
11732     }
11733   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11734     {
11735       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11736       return -99;
11737     }
11738   if (next == 0)
11739     {
11740       errmsg ("next node required");
11741       return -99;
11742     }
11743   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11744     {
11745       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11746       return -99;
11747     }
11748
11749   M (ADD_NODE_NEXT, mp);
11750   clib_memcpy (mp->node_name, name, vec_len (name));
11751   clib_memcpy (mp->next_name, next, vec_len (next));
11752   vec_free (name);
11753   vec_free (next);
11754
11755   S (mp);
11756   W (ret);
11757   return ret;
11758 }
11759
11760 static int
11761 api_l2tpv3_create_tunnel (vat_main_t * vam)
11762 {
11763   unformat_input_t *i = vam->input;
11764   ip6_address_t client_address, our_address;
11765   int client_address_set = 0;
11766   int our_address_set = 0;
11767   u32 local_session_id = 0;
11768   u32 remote_session_id = 0;
11769   u64 local_cookie = 0;
11770   u64 remote_cookie = 0;
11771   u8 l2_sublayer_present = 0;
11772   vl_api_l2tpv3_create_tunnel_t *mp;
11773   int ret;
11774
11775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11776     {
11777       if (unformat (i, "client_address %U", unformat_ip6_address,
11778                     &client_address))
11779         client_address_set = 1;
11780       else if (unformat (i, "our_address %U", unformat_ip6_address,
11781                          &our_address))
11782         our_address_set = 1;
11783       else if (unformat (i, "local_session_id %d", &local_session_id))
11784         ;
11785       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11786         ;
11787       else if (unformat (i, "local_cookie %lld", &local_cookie))
11788         ;
11789       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11790         ;
11791       else if (unformat (i, "l2-sublayer-present"))
11792         l2_sublayer_present = 1;
11793       else
11794         break;
11795     }
11796
11797   if (client_address_set == 0)
11798     {
11799       errmsg ("client_address required");
11800       return -99;
11801     }
11802
11803   if (our_address_set == 0)
11804     {
11805       errmsg ("our_address required");
11806       return -99;
11807     }
11808
11809   M (L2TPV3_CREATE_TUNNEL, mp);
11810
11811   clib_memcpy (mp->client_address, client_address.as_u8,
11812                sizeof (mp->client_address));
11813
11814   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11815
11816   mp->local_session_id = ntohl (local_session_id);
11817   mp->remote_session_id = ntohl (remote_session_id);
11818   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11819   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11820   mp->l2_sublayer_present = l2_sublayer_present;
11821   mp->is_ipv6 = 1;
11822
11823   S (mp);
11824   W (ret);
11825   return ret;
11826 }
11827
11828 static int
11829 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   u32 sw_if_index;
11833   u8 sw_if_index_set = 0;
11834   u64 new_local_cookie = 0;
11835   u64 new_remote_cookie = 0;
11836   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11837   int ret;
11838
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11842         sw_if_index_set = 1;
11843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11844         sw_if_index_set = 1;
11845       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11846         ;
11847       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11848         ;
11849       else
11850         break;
11851     }
11852
11853   if (sw_if_index_set == 0)
11854     {
11855       errmsg ("missing interface name or sw_if_index");
11856       return -99;
11857     }
11858
11859   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11860
11861   mp->sw_if_index = ntohl (sw_if_index);
11862   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11863   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11864
11865   S (mp);
11866   W (ret);
11867   return ret;
11868 }
11869
11870 static int
11871 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11872 {
11873   unformat_input_t *i = vam->input;
11874   vl_api_l2tpv3_interface_enable_disable_t *mp;
11875   u32 sw_if_index;
11876   u8 sw_if_index_set = 0;
11877   u8 enable_disable = 1;
11878   int ret;
11879
11880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11881     {
11882       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11883         sw_if_index_set = 1;
11884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11885         sw_if_index_set = 1;
11886       else if (unformat (i, "enable"))
11887         enable_disable = 1;
11888       else if (unformat (i, "disable"))
11889         enable_disable = 0;
11890       else
11891         break;
11892     }
11893
11894   if (sw_if_index_set == 0)
11895     {
11896       errmsg ("missing interface name or sw_if_index");
11897       return -99;
11898     }
11899
11900   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11901
11902   mp->sw_if_index = ntohl (sw_if_index);
11903   mp->enable_disable = enable_disable;
11904
11905   S (mp);
11906   W (ret);
11907   return ret;
11908 }
11909
11910 static int
11911 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11912 {
11913   unformat_input_t *i = vam->input;
11914   vl_api_l2tpv3_set_lookup_key_t *mp;
11915   u8 key = ~0;
11916   int ret;
11917
11918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (i, "lookup_v6_src"))
11921         key = L2T_LOOKUP_SRC_ADDRESS;
11922       else if (unformat (i, "lookup_v6_dst"))
11923         key = L2T_LOOKUP_DST_ADDRESS;
11924       else if (unformat (i, "lookup_session_id"))
11925         key = L2T_LOOKUP_SESSION_ID;
11926       else
11927         break;
11928     }
11929
11930   if (key == (u8) ~ 0)
11931     {
11932       errmsg ("l2tp session lookup key unset");
11933       return -99;
11934     }
11935
11936   M (L2TPV3_SET_LOOKUP_KEY, mp);
11937
11938   mp->key = key;
11939
11940   S (mp);
11941   W (ret);
11942   return ret;
11943 }
11944
11945 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11946   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11947 {
11948   vat_main_t *vam = &vat_main;
11949
11950   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11951          format_ip6_address, mp->our_address,
11952          format_ip6_address, mp->client_address,
11953          clib_net_to_host_u32 (mp->sw_if_index));
11954
11955   print (vam->ofp,
11956          "   local cookies %016llx %016llx remote cookie %016llx",
11957          clib_net_to_host_u64 (mp->local_cookie[0]),
11958          clib_net_to_host_u64 (mp->local_cookie[1]),
11959          clib_net_to_host_u64 (mp->remote_cookie));
11960
11961   print (vam->ofp, "   local session-id %d remote session-id %d",
11962          clib_net_to_host_u32 (mp->local_session_id),
11963          clib_net_to_host_u32 (mp->remote_session_id));
11964
11965   print (vam->ofp, "   l2 specific sublayer %s\n",
11966          mp->l2_sublayer_present ? "preset" : "absent");
11967
11968 }
11969
11970 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11971   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11972 {
11973   vat_main_t *vam = &vat_main;
11974   vat_json_node_t *node = NULL;
11975   struct in6_addr addr;
11976
11977   if (VAT_JSON_ARRAY != vam->json_tree.type)
11978     {
11979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11980       vat_json_init_array (&vam->json_tree);
11981     }
11982   node = vat_json_array_add (&vam->json_tree);
11983
11984   vat_json_init_object (node);
11985
11986   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11987   vat_json_object_add_ip6 (node, "our_address", addr);
11988   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11989   vat_json_object_add_ip6 (node, "client_address", addr);
11990
11991   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11992   vat_json_init_array (lc);
11993   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11994   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11995   vat_json_object_add_uint (node, "remote_cookie",
11996                             clib_net_to_host_u64 (mp->remote_cookie));
11997
11998   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11999   vat_json_object_add_uint (node, "local_session_id",
12000                             clib_net_to_host_u32 (mp->local_session_id));
12001   vat_json_object_add_uint (node, "remote_session_id",
12002                             clib_net_to_host_u32 (mp->remote_session_id));
12003   vat_json_object_add_string_copy (node, "l2_sublayer",
12004                                    mp->l2_sublayer_present ? (u8 *) "present"
12005                                    : (u8 *) "absent");
12006 }
12007
12008 static int
12009 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12010 {
12011   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12012   vl_api_control_ping_t *mp_ping;
12013   int ret;
12014
12015   /* Get list of l2tpv3-tunnel interfaces */
12016   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12017   S (mp);
12018
12019   /* Use a control ping for synchronization */
12020   MPING (CONTROL_PING, mp_ping);
12021   S (mp_ping);
12022
12023   W (ret);
12024   return ret;
12025 }
12026
12027
12028 static void vl_api_sw_interface_tap_details_t_handler
12029   (vl_api_sw_interface_tap_details_t * mp)
12030 {
12031   vat_main_t *vam = &vat_main;
12032
12033   print (vam->ofp, "%-16s %d",
12034          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12035 }
12036
12037 static void vl_api_sw_interface_tap_details_t_handler_json
12038   (vl_api_sw_interface_tap_details_t * mp)
12039 {
12040   vat_main_t *vam = &vat_main;
12041   vat_json_node_t *node = NULL;
12042
12043   if (VAT_JSON_ARRAY != vam->json_tree.type)
12044     {
12045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12046       vat_json_init_array (&vam->json_tree);
12047     }
12048   node = vat_json_array_add (&vam->json_tree);
12049
12050   vat_json_init_object (node);
12051   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12052   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12053 }
12054
12055 static int
12056 api_sw_interface_tap_dump (vat_main_t * vam)
12057 {
12058   vl_api_sw_interface_tap_dump_t *mp;
12059   vl_api_control_ping_t *mp_ping;
12060   int ret;
12061
12062   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12063   /* Get list of tap interfaces */
12064   M (SW_INTERFACE_TAP_DUMP, mp);
12065   S (mp);
12066
12067   /* Use a control ping for synchronization */
12068   MPING (CONTROL_PING, mp_ping);
12069   S (mp_ping);
12070
12071   W (ret);
12072   return ret;
12073 }
12074
12075 static uword unformat_vxlan_decap_next
12076   (unformat_input_t * input, va_list * args)
12077 {
12078   u32 *result = va_arg (*args, u32 *);
12079   u32 tmp;
12080
12081   if (unformat (input, "l2"))
12082     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12083   else if (unformat (input, "%d", &tmp))
12084     *result = tmp;
12085   else
12086     return 0;
12087   return 1;
12088 }
12089
12090 static int
12091 api_vxlan_add_del_tunnel (vat_main_t * vam)
12092 {
12093   unformat_input_t *line_input = vam->input;
12094   vl_api_vxlan_add_del_tunnel_t *mp;
12095   ip46_address_t src, dst;
12096   u8 is_add = 1;
12097   u8 ipv4_set = 0, ipv6_set = 0;
12098   u8 src_set = 0;
12099   u8 dst_set = 0;
12100   u8 grp_set = 0;
12101   u32 mcast_sw_if_index = ~0;
12102   u32 encap_vrf_id = 0;
12103   u32 decap_next_index = ~0;
12104   u32 vni = 0;
12105   int ret;
12106
12107   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12108   memset (&src, 0, sizeof src);
12109   memset (&dst, 0, sizeof dst);
12110
12111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12112     {
12113       if (unformat (line_input, "del"))
12114         is_add = 0;
12115       else
12116         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12117         {
12118           ipv4_set = 1;
12119           src_set = 1;
12120         }
12121       else
12122         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12123         {
12124           ipv4_set = 1;
12125           dst_set = 1;
12126         }
12127       else
12128         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12129         {
12130           ipv6_set = 1;
12131           src_set = 1;
12132         }
12133       else
12134         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12135         {
12136           ipv6_set = 1;
12137           dst_set = 1;
12138         }
12139       else if (unformat (line_input, "group %U %U",
12140                          unformat_ip4_address, &dst.ip4,
12141                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12142         {
12143           grp_set = dst_set = 1;
12144           ipv4_set = 1;
12145         }
12146       else if (unformat (line_input, "group %U",
12147                          unformat_ip4_address, &dst.ip4))
12148         {
12149           grp_set = dst_set = 1;
12150           ipv4_set = 1;
12151         }
12152       else if (unformat (line_input, "group %U %U",
12153                          unformat_ip6_address, &dst.ip6,
12154                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12155         {
12156           grp_set = dst_set = 1;
12157           ipv6_set = 1;
12158         }
12159       else if (unformat (line_input, "group %U",
12160                          unformat_ip6_address, &dst.ip6))
12161         {
12162           grp_set = dst_set = 1;
12163           ipv6_set = 1;
12164         }
12165       else
12166         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12167         ;
12168       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12169         ;
12170       else if (unformat (line_input, "decap-next %U",
12171                          unformat_vxlan_decap_next, &decap_next_index))
12172         ;
12173       else if (unformat (line_input, "vni %d", &vni))
12174         ;
12175       else
12176         {
12177           errmsg ("parse error '%U'", format_unformat_error, line_input);
12178           return -99;
12179         }
12180     }
12181
12182   if (src_set == 0)
12183     {
12184       errmsg ("tunnel src address not specified");
12185       return -99;
12186     }
12187   if (dst_set == 0)
12188     {
12189       errmsg ("tunnel dst address not specified");
12190       return -99;
12191     }
12192
12193   if (grp_set && !ip46_address_is_multicast (&dst))
12194     {
12195       errmsg ("tunnel group address not multicast");
12196       return -99;
12197     }
12198   if (grp_set && mcast_sw_if_index == ~0)
12199     {
12200       errmsg ("tunnel nonexistent multicast device");
12201       return -99;
12202     }
12203   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12204     {
12205       errmsg ("tunnel dst address must be unicast");
12206       return -99;
12207     }
12208
12209
12210   if (ipv4_set && ipv6_set)
12211     {
12212       errmsg ("both IPv4 and IPv6 addresses specified");
12213       return -99;
12214     }
12215
12216   if ((vni == 0) || (vni >> 24))
12217     {
12218       errmsg ("vni not specified or out of range");
12219       return -99;
12220     }
12221
12222   M (VXLAN_ADD_DEL_TUNNEL, mp);
12223
12224   if (ipv6_set)
12225     {
12226       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12227       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12228     }
12229   else
12230     {
12231       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12232       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12233     }
12234   mp->encap_vrf_id = ntohl (encap_vrf_id);
12235   mp->decap_next_index = ntohl (decap_next_index);
12236   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12237   mp->vni = ntohl (vni);
12238   mp->is_add = is_add;
12239   mp->is_ipv6 = ipv6_set;
12240
12241   S (mp);
12242   W (ret);
12243   return ret;
12244 }
12245
12246 static void vl_api_vxlan_tunnel_details_t_handler
12247   (vl_api_vxlan_tunnel_details_t * mp)
12248 {
12249   vat_main_t *vam = &vat_main;
12250   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12251   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12252
12253   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12254          ntohl (mp->sw_if_index),
12255          format_ip46_address, &src, IP46_TYPE_ANY,
12256          format_ip46_address, &dst, IP46_TYPE_ANY,
12257          ntohl (mp->encap_vrf_id),
12258          ntohl (mp->decap_next_index), ntohl (mp->vni),
12259          ntohl (mp->mcast_sw_if_index));
12260 }
12261
12262 static void vl_api_vxlan_tunnel_details_t_handler_json
12263   (vl_api_vxlan_tunnel_details_t * mp)
12264 {
12265   vat_main_t *vam = &vat_main;
12266   vat_json_node_t *node = NULL;
12267
12268   if (VAT_JSON_ARRAY != vam->json_tree.type)
12269     {
12270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12271       vat_json_init_array (&vam->json_tree);
12272     }
12273   node = vat_json_array_add (&vam->json_tree);
12274
12275   vat_json_init_object (node);
12276   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12277   if (mp->is_ipv6)
12278     {
12279       struct in6_addr ip6;
12280
12281       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12282       vat_json_object_add_ip6 (node, "src_address", ip6);
12283       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12284       vat_json_object_add_ip6 (node, "dst_address", ip6);
12285     }
12286   else
12287     {
12288       struct in_addr ip4;
12289
12290       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12291       vat_json_object_add_ip4 (node, "src_address", ip4);
12292       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12293       vat_json_object_add_ip4 (node, "dst_address", ip4);
12294     }
12295   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12296   vat_json_object_add_uint (node, "decap_next_index",
12297                             ntohl (mp->decap_next_index));
12298   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12299   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12300   vat_json_object_add_uint (node, "mcast_sw_if_index",
12301                             ntohl (mp->mcast_sw_if_index));
12302 }
12303
12304 static int
12305 api_vxlan_tunnel_dump (vat_main_t * vam)
12306 {
12307   unformat_input_t *i = vam->input;
12308   vl_api_vxlan_tunnel_dump_t *mp;
12309   vl_api_control_ping_t *mp_ping;
12310   u32 sw_if_index;
12311   u8 sw_if_index_set = 0;
12312   int ret;
12313
12314   /* Parse args required to build the message */
12315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (i, "sw_if_index %d", &sw_if_index))
12318         sw_if_index_set = 1;
12319       else
12320         break;
12321     }
12322
12323   if (sw_if_index_set == 0)
12324     {
12325       sw_if_index = ~0;
12326     }
12327
12328   if (!vam->json_output)
12329     {
12330       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12331              "sw_if_index", "src_address", "dst_address",
12332              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12333     }
12334
12335   /* Get list of vxlan-tunnel interfaces */
12336   M (VXLAN_TUNNEL_DUMP, mp);
12337
12338   mp->sw_if_index = htonl (sw_if_index);
12339
12340   S (mp);
12341
12342   /* Use a control ping for synchronization */
12343   MPING (CONTROL_PING, mp_ping);
12344   S (mp_ping);
12345
12346   W (ret);
12347   return ret;
12348 }
12349
12350 static uword unformat_geneve_decap_next
12351   (unformat_input_t * input, va_list * args)
12352 {
12353   u32 *result = va_arg (*args, u32 *);
12354   u32 tmp;
12355
12356   if (unformat (input, "l2"))
12357     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12358   else if (unformat (input, "%d", &tmp))
12359     *result = tmp;
12360   else
12361     return 0;
12362   return 1;
12363 }
12364
12365 static int
12366 api_geneve_add_del_tunnel (vat_main_t * vam)
12367 {
12368   unformat_input_t *line_input = vam->input;
12369   vl_api_geneve_add_del_tunnel_t *mp;
12370   ip46_address_t src, dst;
12371   u8 is_add = 1;
12372   u8 ipv4_set = 0, ipv6_set = 0;
12373   u8 src_set = 0;
12374   u8 dst_set = 0;
12375   u8 grp_set = 0;
12376   u32 mcast_sw_if_index = ~0;
12377   u32 encap_vrf_id = 0;
12378   u32 decap_next_index = ~0;
12379   u32 vni = 0;
12380   int ret;
12381
12382   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12383   memset (&src, 0, sizeof src);
12384   memset (&dst, 0, sizeof dst);
12385
12386   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12387     {
12388       if (unformat (line_input, "del"))
12389         is_add = 0;
12390       else
12391         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12392         {
12393           ipv4_set = 1;
12394           src_set = 1;
12395         }
12396       else
12397         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12398         {
12399           ipv4_set = 1;
12400           dst_set = 1;
12401         }
12402       else
12403         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12404         {
12405           ipv6_set = 1;
12406           src_set = 1;
12407         }
12408       else
12409         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12410         {
12411           ipv6_set = 1;
12412           dst_set = 1;
12413         }
12414       else if (unformat (line_input, "group %U %U",
12415                          unformat_ip4_address, &dst.ip4,
12416                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12417         {
12418           grp_set = dst_set = 1;
12419           ipv4_set = 1;
12420         }
12421       else if (unformat (line_input, "group %U",
12422                          unformat_ip4_address, &dst.ip4))
12423         {
12424           grp_set = dst_set = 1;
12425           ipv4_set = 1;
12426         }
12427       else if (unformat (line_input, "group %U %U",
12428                          unformat_ip6_address, &dst.ip6,
12429                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12430         {
12431           grp_set = dst_set = 1;
12432           ipv6_set = 1;
12433         }
12434       else if (unformat (line_input, "group %U",
12435                          unformat_ip6_address, &dst.ip6))
12436         {
12437           grp_set = dst_set = 1;
12438           ipv6_set = 1;
12439         }
12440       else
12441         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12442         ;
12443       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12444         ;
12445       else if (unformat (line_input, "decap-next %U",
12446                          unformat_geneve_decap_next, &decap_next_index))
12447         ;
12448       else if (unformat (line_input, "vni %d", &vni))
12449         ;
12450       else
12451         {
12452           errmsg ("parse error '%U'", format_unformat_error, line_input);
12453           return -99;
12454         }
12455     }
12456
12457   if (src_set == 0)
12458     {
12459       errmsg ("tunnel src address not specified");
12460       return -99;
12461     }
12462   if (dst_set == 0)
12463     {
12464       errmsg ("tunnel dst address not specified");
12465       return -99;
12466     }
12467
12468   if (grp_set && !ip46_address_is_multicast (&dst))
12469     {
12470       errmsg ("tunnel group address not multicast");
12471       return -99;
12472     }
12473   if (grp_set && mcast_sw_if_index == ~0)
12474     {
12475       errmsg ("tunnel nonexistent multicast device");
12476       return -99;
12477     }
12478   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12479     {
12480       errmsg ("tunnel dst address must be unicast");
12481       return -99;
12482     }
12483
12484
12485   if (ipv4_set && ipv6_set)
12486     {
12487       errmsg ("both IPv4 and IPv6 addresses specified");
12488       return -99;
12489     }
12490
12491   if ((vni == 0) || (vni >> 24))
12492     {
12493       errmsg ("vni not specified or out of range");
12494       return -99;
12495     }
12496
12497   M (GENEVE_ADD_DEL_TUNNEL, mp);
12498
12499   if (ipv6_set)
12500     {
12501       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12502       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12503     }
12504   else
12505     {
12506       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12507       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12508     }
12509   mp->encap_vrf_id = ntohl (encap_vrf_id);
12510   mp->decap_next_index = ntohl (decap_next_index);
12511   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12512   mp->vni = ntohl (vni);
12513   mp->is_add = is_add;
12514   mp->is_ipv6 = ipv6_set;
12515
12516   S (mp);
12517   W (ret);
12518   return ret;
12519 }
12520
12521 static void vl_api_geneve_tunnel_details_t_handler
12522   (vl_api_geneve_tunnel_details_t * mp)
12523 {
12524   vat_main_t *vam = &vat_main;
12525   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12526   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12527
12528   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12529          ntohl (mp->sw_if_index),
12530          format_ip46_address, &src, IP46_TYPE_ANY,
12531          format_ip46_address, &dst, IP46_TYPE_ANY,
12532          ntohl (mp->encap_vrf_id),
12533          ntohl (mp->decap_next_index), ntohl (mp->vni),
12534          ntohl (mp->mcast_sw_if_index));
12535 }
12536
12537 static void vl_api_geneve_tunnel_details_t_handler_json
12538   (vl_api_geneve_tunnel_details_t * mp)
12539 {
12540   vat_main_t *vam = &vat_main;
12541   vat_json_node_t *node = NULL;
12542
12543   if (VAT_JSON_ARRAY != vam->json_tree.type)
12544     {
12545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12546       vat_json_init_array (&vam->json_tree);
12547     }
12548   node = vat_json_array_add (&vam->json_tree);
12549
12550   vat_json_init_object (node);
12551   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12552   if (mp->is_ipv6)
12553     {
12554       struct in6_addr ip6;
12555
12556       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12557       vat_json_object_add_ip6 (node, "src_address", ip6);
12558       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12559       vat_json_object_add_ip6 (node, "dst_address", ip6);
12560     }
12561   else
12562     {
12563       struct in_addr ip4;
12564
12565       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12566       vat_json_object_add_ip4 (node, "src_address", ip4);
12567       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12568       vat_json_object_add_ip4 (node, "dst_address", ip4);
12569     }
12570   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12571   vat_json_object_add_uint (node, "decap_next_index",
12572                             ntohl (mp->decap_next_index));
12573   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12574   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12575   vat_json_object_add_uint (node, "mcast_sw_if_index",
12576                             ntohl (mp->mcast_sw_if_index));
12577 }
12578
12579 static int
12580 api_geneve_tunnel_dump (vat_main_t * vam)
12581 {
12582   unformat_input_t *i = vam->input;
12583   vl_api_geneve_tunnel_dump_t *mp;
12584   vl_api_control_ping_t *mp_ping;
12585   u32 sw_if_index;
12586   u8 sw_if_index_set = 0;
12587   int ret;
12588
12589   /* Parse args required to build the message */
12590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12591     {
12592       if (unformat (i, "sw_if_index %d", &sw_if_index))
12593         sw_if_index_set = 1;
12594       else
12595         break;
12596     }
12597
12598   if (sw_if_index_set == 0)
12599     {
12600       sw_if_index = ~0;
12601     }
12602
12603   if (!vam->json_output)
12604     {
12605       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12606              "sw_if_index", "local_address", "remote_address",
12607              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12608     }
12609
12610   /* Get list of geneve-tunnel interfaces */
12611   M (GENEVE_TUNNEL_DUMP, mp);
12612
12613   mp->sw_if_index = htonl (sw_if_index);
12614
12615   S (mp);
12616
12617   /* Use a control ping for synchronization */
12618   M (CONTROL_PING, mp_ping);
12619   S (mp_ping);
12620
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static int
12626 api_gre_add_del_tunnel (vat_main_t * vam)
12627 {
12628   unformat_input_t *line_input = vam->input;
12629   vl_api_gre_add_del_tunnel_t *mp;
12630   ip4_address_t src4, dst4;
12631   ip6_address_t src6, dst6;
12632   u8 is_add = 1;
12633   u8 ipv4_set = 0;
12634   u8 ipv6_set = 0;
12635   u8 teb = 0;
12636   u8 src_set = 0;
12637   u8 dst_set = 0;
12638   u32 outer_fib_id = 0;
12639   int ret;
12640
12641   memset (&src4, 0, sizeof src4);
12642   memset (&dst4, 0, sizeof dst4);
12643   memset (&src6, 0, sizeof src6);
12644   memset (&dst6, 0, sizeof dst6);
12645
12646   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12647     {
12648       if (unformat (line_input, "del"))
12649         is_add = 0;
12650       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12651         {
12652           src_set = 1;
12653           ipv4_set = 1;
12654         }
12655       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12656         {
12657           dst_set = 1;
12658           ipv4_set = 1;
12659         }
12660       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12661         {
12662           src_set = 1;
12663           ipv6_set = 1;
12664         }
12665       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12666         {
12667           dst_set = 1;
12668           ipv6_set = 1;
12669         }
12670       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12671         ;
12672       else if (unformat (line_input, "teb"))
12673         teb = 1;
12674       else
12675         {
12676           errmsg ("parse error '%U'", format_unformat_error, line_input);
12677           return -99;
12678         }
12679     }
12680
12681   if (src_set == 0)
12682     {
12683       errmsg ("tunnel src address not specified");
12684       return -99;
12685     }
12686   if (dst_set == 0)
12687     {
12688       errmsg ("tunnel dst address not specified");
12689       return -99;
12690     }
12691   if (ipv4_set && ipv6_set)
12692     {
12693       errmsg ("both IPv4 and IPv6 addresses specified");
12694       return -99;
12695     }
12696
12697
12698   M (GRE_ADD_DEL_TUNNEL, mp);
12699
12700   if (ipv4_set)
12701     {
12702       clib_memcpy (&mp->src_address, &src4, 4);
12703       clib_memcpy (&mp->dst_address, &dst4, 4);
12704     }
12705   else
12706     {
12707       clib_memcpy (&mp->src_address, &src6, 16);
12708       clib_memcpy (&mp->dst_address, &dst6, 16);
12709     }
12710   mp->outer_fib_id = ntohl (outer_fib_id);
12711   mp->is_add = is_add;
12712   mp->teb = teb;
12713   mp->is_ipv6 = ipv6_set;
12714
12715   S (mp);
12716   W (ret);
12717   return ret;
12718 }
12719
12720 static void vl_api_gre_tunnel_details_t_handler
12721   (vl_api_gre_tunnel_details_t * mp)
12722 {
12723   vat_main_t *vam = &vat_main;
12724   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12725   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12726
12727   print (vam->ofp, "%11d%24U%24U%6d%14d",
12728          ntohl (mp->sw_if_index),
12729          format_ip46_address, &src, IP46_TYPE_ANY,
12730          format_ip46_address, &dst, IP46_TYPE_ANY,
12731          mp->teb, ntohl (mp->outer_fib_id));
12732 }
12733
12734 static void vl_api_gre_tunnel_details_t_handler_json
12735   (vl_api_gre_tunnel_details_t * mp)
12736 {
12737   vat_main_t *vam = &vat_main;
12738   vat_json_node_t *node = NULL;
12739   struct in_addr ip4;
12740   struct in6_addr ip6;
12741
12742   if (VAT_JSON_ARRAY != vam->json_tree.type)
12743     {
12744       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12745       vat_json_init_array (&vam->json_tree);
12746     }
12747   node = vat_json_array_add (&vam->json_tree);
12748
12749   vat_json_init_object (node);
12750   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12751   if (!mp->is_ipv6)
12752     {
12753       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12754       vat_json_object_add_ip4 (node, "src_address", ip4);
12755       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12756       vat_json_object_add_ip4 (node, "dst_address", ip4);
12757     }
12758   else
12759     {
12760       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12761       vat_json_object_add_ip6 (node, "src_address", ip6);
12762       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12763       vat_json_object_add_ip6 (node, "dst_address", ip6);
12764     }
12765   vat_json_object_add_uint (node, "teb", mp->teb);
12766   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12767   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12768 }
12769
12770 static int
12771 api_gre_tunnel_dump (vat_main_t * vam)
12772 {
12773   unformat_input_t *i = vam->input;
12774   vl_api_gre_tunnel_dump_t *mp;
12775   vl_api_control_ping_t *mp_ping;
12776   u32 sw_if_index;
12777   u8 sw_if_index_set = 0;
12778   int ret;
12779
12780   /* Parse args required to build the message */
12781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12782     {
12783       if (unformat (i, "sw_if_index %d", &sw_if_index))
12784         sw_if_index_set = 1;
12785       else
12786         break;
12787     }
12788
12789   if (sw_if_index_set == 0)
12790     {
12791       sw_if_index = ~0;
12792     }
12793
12794   if (!vam->json_output)
12795     {
12796       print (vam->ofp, "%11s%24s%24s%6s%14s",
12797              "sw_if_index", "src_address", "dst_address", "teb",
12798              "outer_fib_id");
12799     }
12800
12801   /* Get list of gre-tunnel interfaces */
12802   M (GRE_TUNNEL_DUMP, mp);
12803
12804   mp->sw_if_index = htonl (sw_if_index);
12805
12806   S (mp);
12807
12808   /* Use a control ping for synchronization */
12809   MPING (CONTROL_PING, mp_ping);
12810   S (mp_ping);
12811
12812   W (ret);
12813   return ret;
12814 }
12815
12816 static int
12817 api_l2_fib_clear_table (vat_main_t * vam)
12818 {
12819 //  unformat_input_t * i = vam->input;
12820   vl_api_l2_fib_clear_table_t *mp;
12821   int ret;
12822
12823   M (L2_FIB_CLEAR_TABLE, mp);
12824
12825   S (mp);
12826   W (ret);
12827   return ret;
12828 }
12829
12830 static int
12831 api_l2_interface_efp_filter (vat_main_t * vam)
12832 {
12833   unformat_input_t *i = vam->input;
12834   vl_api_l2_interface_efp_filter_t *mp;
12835   u32 sw_if_index;
12836   u8 enable = 1;
12837   u8 sw_if_index_set = 0;
12838   int ret;
12839
12840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12841     {
12842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12843         sw_if_index_set = 1;
12844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12845         sw_if_index_set = 1;
12846       else if (unformat (i, "enable"))
12847         enable = 1;
12848       else if (unformat (i, "disable"))
12849         enable = 0;
12850       else
12851         {
12852           clib_warning ("parse error '%U'", format_unformat_error, i);
12853           return -99;
12854         }
12855     }
12856
12857   if (sw_if_index_set == 0)
12858     {
12859       errmsg ("missing sw_if_index");
12860       return -99;
12861     }
12862
12863   M (L2_INTERFACE_EFP_FILTER, mp);
12864
12865   mp->sw_if_index = ntohl (sw_if_index);
12866   mp->enable_disable = enable;
12867
12868   S (mp);
12869   W (ret);
12870   return ret;
12871 }
12872
12873 #define foreach_vtr_op                          \
12874 _("disable",  L2_VTR_DISABLED)                  \
12875 _("push-1",  L2_VTR_PUSH_1)                     \
12876 _("push-2",  L2_VTR_PUSH_2)                     \
12877 _("pop-1",  L2_VTR_POP_1)                       \
12878 _("pop-2",  L2_VTR_POP_2)                       \
12879 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12880 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12881 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12882 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12883
12884 static int
12885 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12886 {
12887   unformat_input_t *i = vam->input;
12888   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12889   u32 sw_if_index;
12890   u8 sw_if_index_set = 0;
12891   u8 vtr_op_set = 0;
12892   u32 vtr_op = 0;
12893   u32 push_dot1q = 1;
12894   u32 tag1 = ~0;
12895   u32 tag2 = ~0;
12896   int ret;
12897
12898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12899     {
12900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12901         sw_if_index_set = 1;
12902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12903         sw_if_index_set = 1;
12904       else if (unformat (i, "vtr_op %d", &vtr_op))
12905         vtr_op_set = 1;
12906 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12907       foreach_vtr_op
12908 #undef _
12909         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12910         ;
12911       else if (unformat (i, "tag1 %d", &tag1))
12912         ;
12913       else if (unformat (i, "tag2 %d", &tag2))
12914         ;
12915       else
12916         {
12917           clib_warning ("parse error '%U'", format_unformat_error, i);
12918           return -99;
12919         }
12920     }
12921
12922   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12923     {
12924       errmsg ("missing vtr operation or sw_if_index");
12925       return -99;
12926     }
12927
12928   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12929   mp->sw_if_index = ntohl (sw_if_index);
12930   mp->vtr_op = ntohl (vtr_op);
12931   mp->push_dot1q = ntohl (push_dot1q);
12932   mp->tag1 = ntohl (tag1);
12933   mp->tag2 = ntohl (tag2);
12934
12935   S (mp);
12936   W (ret);
12937   return ret;
12938 }
12939
12940 static int
12941 api_create_vhost_user_if (vat_main_t * vam)
12942 {
12943   unformat_input_t *i = vam->input;
12944   vl_api_create_vhost_user_if_t *mp;
12945   u8 *file_name;
12946   u8 is_server = 0;
12947   u8 file_name_set = 0;
12948   u32 custom_dev_instance = ~0;
12949   u8 hwaddr[6];
12950   u8 use_custom_mac = 0;
12951   u8 *tag = 0;
12952   int ret;
12953
12954   /* Shut up coverity */
12955   memset (hwaddr, 0, sizeof (hwaddr));
12956
12957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (i, "socket %s", &file_name))
12960         {
12961           file_name_set = 1;
12962         }
12963       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12964         ;
12965       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12966         use_custom_mac = 1;
12967       else if (unformat (i, "server"))
12968         is_server = 1;
12969       else if (unformat (i, "tag %s", &tag))
12970         ;
12971       else
12972         break;
12973     }
12974
12975   if (file_name_set == 0)
12976     {
12977       errmsg ("missing socket file name");
12978       return -99;
12979     }
12980
12981   if (vec_len (file_name) > 255)
12982     {
12983       errmsg ("socket file name too long");
12984       return -99;
12985     }
12986   vec_add1 (file_name, 0);
12987
12988   M (CREATE_VHOST_USER_IF, mp);
12989
12990   mp->is_server = is_server;
12991   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12992   vec_free (file_name);
12993   if (custom_dev_instance != ~0)
12994     {
12995       mp->renumber = 1;
12996       mp->custom_dev_instance = ntohl (custom_dev_instance);
12997     }
12998   mp->use_custom_mac = use_custom_mac;
12999   clib_memcpy (mp->mac_address, hwaddr, 6);
13000   if (tag)
13001     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13002   vec_free (tag);
13003
13004   S (mp);
13005   W (ret);
13006   return ret;
13007 }
13008
13009 static int
13010 api_modify_vhost_user_if (vat_main_t * vam)
13011 {
13012   unformat_input_t *i = vam->input;
13013   vl_api_modify_vhost_user_if_t *mp;
13014   u8 *file_name;
13015   u8 is_server = 0;
13016   u8 file_name_set = 0;
13017   u32 custom_dev_instance = ~0;
13018   u8 sw_if_index_set = 0;
13019   u32 sw_if_index = (u32) ~ 0;
13020   int ret;
13021
13022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13023     {
13024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13025         sw_if_index_set = 1;
13026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13027         sw_if_index_set = 1;
13028       else if (unformat (i, "socket %s", &file_name))
13029         {
13030           file_name_set = 1;
13031         }
13032       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13033         ;
13034       else if (unformat (i, "server"))
13035         is_server = 1;
13036       else
13037         break;
13038     }
13039
13040   if (sw_if_index_set == 0)
13041     {
13042       errmsg ("missing sw_if_index or interface name");
13043       return -99;
13044     }
13045
13046   if (file_name_set == 0)
13047     {
13048       errmsg ("missing socket file name");
13049       return -99;
13050     }
13051
13052   if (vec_len (file_name) > 255)
13053     {
13054       errmsg ("socket file name too long");
13055       return -99;
13056     }
13057   vec_add1 (file_name, 0);
13058
13059   M (MODIFY_VHOST_USER_IF, mp);
13060
13061   mp->sw_if_index = ntohl (sw_if_index);
13062   mp->is_server = is_server;
13063   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13064   vec_free (file_name);
13065   if (custom_dev_instance != ~0)
13066     {
13067       mp->renumber = 1;
13068       mp->custom_dev_instance = ntohl (custom_dev_instance);
13069     }
13070
13071   S (mp);
13072   W (ret);
13073   return ret;
13074 }
13075
13076 static int
13077 api_delete_vhost_user_if (vat_main_t * vam)
13078 {
13079   unformat_input_t *i = vam->input;
13080   vl_api_delete_vhost_user_if_t *mp;
13081   u32 sw_if_index = ~0;
13082   u8 sw_if_index_set = 0;
13083   int ret;
13084
13085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13086     {
13087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13088         sw_if_index_set = 1;
13089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13090         sw_if_index_set = 1;
13091       else
13092         break;
13093     }
13094
13095   if (sw_if_index_set == 0)
13096     {
13097       errmsg ("missing sw_if_index or interface name");
13098       return -99;
13099     }
13100
13101
13102   M (DELETE_VHOST_USER_IF, mp);
13103
13104   mp->sw_if_index = ntohl (sw_if_index);
13105
13106   S (mp);
13107   W (ret);
13108   return ret;
13109 }
13110
13111 static void vl_api_sw_interface_vhost_user_details_t_handler
13112   (vl_api_sw_interface_vhost_user_details_t * mp)
13113 {
13114   vat_main_t *vam = &vat_main;
13115
13116   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13117          (char *) mp->interface_name,
13118          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13119          clib_net_to_host_u64 (mp->features), mp->is_server,
13120          ntohl (mp->num_regions), (char *) mp->sock_filename);
13121   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13122 }
13123
13124 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13125   (vl_api_sw_interface_vhost_user_details_t * mp)
13126 {
13127   vat_main_t *vam = &vat_main;
13128   vat_json_node_t *node = NULL;
13129
13130   if (VAT_JSON_ARRAY != vam->json_tree.type)
13131     {
13132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13133       vat_json_init_array (&vam->json_tree);
13134     }
13135   node = vat_json_array_add (&vam->json_tree);
13136
13137   vat_json_init_object (node);
13138   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13139   vat_json_object_add_string_copy (node, "interface_name",
13140                                    mp->interface_name);
13141   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13142                             ntohl (mp->virtio_net_hdr_sz));
13143   vat_json_object_add_uint (node, "features",
13144                             clib_net_to_host_u64 (mp->features));
13145   vat_json_object_add_uint (node, "is_server", mp->is_server);
13146   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13147   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13148   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13149 }
13150
13151 static int
13152 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13153 {
13154   vl_api_sw_interface_vhost_user_dump_t *mp;
13155   vl_api_control_ping_t *mp_ping;
13156   int ret;
13157   print (vam->ofp,
13158          "Interface name            idx hdr_sz features server regions filename");
13159
13160   /* Get list of vhost-user interfaces */
13161   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13162   S (mp);
13163
13164   /* Use a control ping for synchronization */
13165   MPING (CONTROL_PING, mp_ping);
13166   S (mp_ping);
13167
13168   W (ret);
13169   return ret;
13170 }
13171
13172 static int
13173 api_show_version (vat_main_t * vam)
13174 {
13175   vl_api_show_version_t *mp;
13176   int ret;
13177
13178   M (SHOW_VERSION, mp);
13179
13180   S (mp);
13181   W (ret);
13182   return ret;
13183 }
13184
13185
13186 static int
13187 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13188 {
13189   unformat_input_t *line_input = vam->input;
13190   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13191   ip4_address_t local4, remote4;
13192   ip6_address_t local6, remote6;
13193   u8 is_add = 1;
13194   u8 ipv4_set = 0, ipv6_set = 0;
13195   u8 local_set = 0;
13196   u8 remote_set = 0;
13197   u8 grp_set = 0;
13198   u32 mcast_sw_if_index = ~0;
13199   u32 encap_vrf_id = 0;
13200   u32 decap_vrf_id = 0;
13201   u8 protocol = ~0;
13202   u32 vni;
13203   u8 vni_set = 0;
13204   int ret;
13205
13206   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13207   memset (&local4, 0, sizeof local4);
13208   memset (&remote4, 0, sizeof remote4);
13209   memset (&local6, 0, sizeof local6);
13210   memset (&remote6, 0, sizeof remote6);
13211
13212   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13213     {
13214       if (unformat (line_input, "del"))
13215         is_add = 0;
13216       else if (unformat (line_input, "local %U",
13217                          unformat_ip4_address, &local4))
13218         {
13219           local_set = 1;
13220           ipv4_set = 1;
13221         }
13222       else if (unformat (line_input, "remote %U",
13223                          unformat_ip4_address, &remote4))
13224         {
13225           remote_set = 1;
13226           ipv4_set = 1;
13227         }
13228       else if (unformat (line_input, "local %U",
13229                          unformat_ip6_address, &local6))
13230         {
13231           local_set = 1;
13232           ipv6_set = 1;
13233         }
13234       else if (unformat (line_input, "remote %U",
13235                          unformat_ip6_address, &remote6))
13236         {
13237           remote_set = 1;
13238           ipv6_set = 1;
13239         }
13240       else if (unformat (line_input, "group %U %U",
13241                          unformat_ip4_address, &remote4,
13242                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13243         {
13244           grp_set = remote_set = 1;
13245           ipv4_set = 1;
13246         }
13247       else if (unformat (line_input, "group %U",
13248                          unformat_ip4_address, &remote4))
13249         {
13250           grp_set = remote_set = 1;
13251           ipv4_set = 1;
13252         }
13253       else if (unformat (line_input, "group %U %U",
13254                          unformat_ip6_address, &remote6,
13255                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13256         {
13257           grp_set = remote_set = 1;
13258           ipv6_set = 1;
13259         }
13260       else if (unformat (line_input, "group %U",
13261                          unformat_ip6_address, &remote6))
13262         {
13263           grp_set = remote_set = 1;
13264           ipv6_set = 1;
13265         }
13266       else
13267         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13268         ;
13269       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13270         ;
13271       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13272         ;
13273       else if (unformat (line_input, "vni %d", &vni))
13274         vni_set = 1;
13275       else if (unformat (line_input, "next-ip4"))
13276         protocol = 1;
13277       else if (unformat (line_input, "next-ip6"))
13278         protocol = 2;
13279       else if (unformat (line_input, "next-ethernet"))
13280         protocol = 3;
13281       else if (unformat (line_input, "next-nsh"))
13282         protocol = 4;
13283       else
13284         {
13285           errmsg ("parse error '%U'", format_unformat_error, line_input);
13286           return -99;
13287         }
13288     }
13289
13290   if (local_set == 0)
13291     {
13292       errmsg ("tunnel local address not specified");
13293       return -99;
13294     }
13295   if (remote_set == 0)
13296     {
13297       errmsg ("tunnel remote address not specified");
13298       return -99;
13299     }
13300   if (grp_set && mcast_sw_if_index == ~0)
13301     {
13302       errmsg ("tunnel nonexistent multicast device");
13303       return -99;
13304     }
13305   if (ipv4_set && ipv6_set)
13306     {
13307       errmsg ("both IPv4 and IPv6 addresses specified");
13308       return -99;
13309     }
13310
13311   if (vni_set == 0)
13312     {
13313       errmsg ("vni not specified");
13314       return -99;
13315     }
13316
13317   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13318
13319
13320   if (ipv6_set)
13321     {
13322       clib_memcpy (&mp->local, &local6, sizeof (local6));
13323       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13324     }
13325   else
13326     {
13327       clib_memcpy (&mp->local, &local4, sizeof (local4));
13328       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13329     }
13330
13331   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13332   mp->encap_vrf_id = ntohl (encap_vrf_id);
13333   mp->decap_vrf_id = ntohl (decap_vrf_id);
13334   mp->protocol = protocol;
13335   mp->vni = ntohl (vni);
13336   mp->is_add = is_add;
13337   mp->is_ipv6 = ipv6_set;
13338
13339   S (mp);
13340   W (ret);
13341   return ret;
13342 }
13343
13344 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13345   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13346 {
13347   vat_main_t *vam = &vat_main;
13348   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13349   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13350
13351   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13352          ntohl (mp->sw_if_index),
13353          format_ip46_address, &local, IP46_TYPE_ANY,
13354          format_ip46_address, &remote, IP46_TYPE_ANY,
13355          ntohl (mp->vni), mp->protocol,
13356          ntohl (mp->mcast_sw_if_index),
13357          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13358 }
13359
13360
13361 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13362   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13363 {
13364   vat_main_t *vam = &vat_main;
13365   vat_json_node_t *node = NULL;
13366   struct in_addr ip4;
13367   struct in6_addr ip6;
13368
13369   if (VAT_JSON_ARRAY != vam->json_tree.type)
13370     {
13371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13372       vat_json_init_array (&vam->json_tree);
13373     }
13374   node = vat_json_array_add (&vam->json_tree);
13375
13376   vat_json_init_object (node);
13377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13378   if (mp->is_ipv6)
13379     {
13380       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13381       vat_json_object_add_ip6 (node, "local", ip6);
13382       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13383       vat_json_object_add_ip6 (node, "remote", ip6);
13384     }
13385   else
13386     {
13387       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13388       vat_json_object_add_ip4 (node, "local", ip4);
13389       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13390       vat_json_object_add_ip4 (node, "remote", ip4);
13391     }
13392   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13393   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13394   vat_json_object_add_uint (node, "mcast_sw_if_index",
13395                             ntohl (mp->mcast_sw_if_index));
13396   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13397   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13398   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13399 }
13400
13401 static int
13402 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13403 {
13404   unformat_input_t *i = vam->input;
13405   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13406   vl_api_control_ping_t *mp_ping;
13407   u32 sw_if_index;
13408   u8 sw_if_index_set = 0;
13409   int ret;
13410
13411   /* Parse args required to build the message */
13412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13413     {
13414       if (unformat (i, "sw_if_index %d", &sw_if_index))
13415         sw_if_index_set = 1;
13416       else
13417         break;
13418     }
13419
13420   if (sw_if_index_set == 0)
13421     {
13422       sw_if_index = ~0;
13423     }
13424
13425   if (!vam->json_output)
13426     {
13427       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13428              "sw_if_index", "local", "remote", "vni",
13429              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13430     }
13431
13432   /* Get list of vxlan-tunnel interfaces */
13433   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13434
13435   mp->sw_if_index = htonl (sw_if_index);
13436
13437   S (mp);
13438
13439   /* Use a control ping for synchronization */
13440   MPING (CONTROL_PING, mp_ping);
13441   S (mp_ping);
13442
13443   W (ret);
13444   return ret;
13445 }
13446
13447 static void vl_api_l2_fib_table_details_t_handler
13448   (vl_api_l2_fib_table_details_t * mp)
13449 {
13450   vat_main_t *vam = &vat_main;
13451
13452   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13453          "       %d       %d     %d",
13454          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13455          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13456          mp->bvi_mac);
13457 }
13458
13459 static void vl_api_l2_fib_table_details_t_handler_json
13460   (vl_api_l2_fib_table_details_t * mp)
13461 {
13462   vat_main_t *vam = &vat_main;
13463   vat_json_node_t *node = NULL;
13464
13465   if (VAT_JSON_ARRAY != vam->json_tree.type)
13466     {
13467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13468       vat_json_init_array (&vam->json_tree);
13469     }
13470   node = vat_json_array_add (&vam->json_tree);
13471
13472   vat_json_init_object (node);
13473   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13474   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13475   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13476   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13477   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13478   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13479 }
13480
13481 static int
13482 api_l2_fib_table_dump (vat_main_t * vam)
13483 {
13484   unformat_input_t *i = vam->input;
13485   vl_api_l2_fib_table_dump_t *mp;
13486   vl_api_control_ping_t *mp_ping;
13487   u32 bd_id;
13488   u8 bd_id_set = 0;
13489   int ret;
13490
13491   /* Parse args required to build the message */
13492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13493     {
13494       if (unformat (i, "bd_id %d", &bd_id))
13495         bd_id_set = 1;
13496       else
13497         break;
13498     }
13499
13500   if (bd_id_set == 0)
13501     {
13502       errmsg ("missing bridge domain");
13503       return -99;
13504     }
13505
13506   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13507
13508   /* Get list of l2 fib entries */
13509   M (L2_FIB_TABLE_DUMP, mp);
13510
13511   mp->bd_id = ntohl (bd_id);
13512   S (mp);
13513
13514   /* Use a control ping for synchronization */
13515   MPING (CONTROL_PING, mp_ping);
13516   S (mp_ping);
13517
13518   W (ret);
13519   return ret;
13520 }
13521
13522
13523 static int
13524 api_interface_name_renumber (vat_main_t * vam)
13525 {
13526   unformat_input_t *line_input = vam->input;
13527   vl_api_interface_name_renumber_t *mp;
13528   u32 sw_if_index = ~0;
13529   u32 new_show_dev_instance = ~0;
13530   int ret;
13531
13532   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13533     {
13534       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13535                     &sw_if_index))
13536         ;
13537       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13538         ;
13539       else if (unformat (line_input, "new_show_dev_instance %d",
13540                          &new_show_dev_instance))
13541         ;
13542       else
13543         break;
13544     }
13545
13546   if (sw_if_index == ~0)
13547     {
13548       errmsg ("missing interface name or sw_if_index");
13549       return -99;
13550     }
13551
13552   if (new_show_dev_instance == ~0)
13553     {
13554       errmsg ("missing new_show_dev_instance");
13555       return -99;
13556     }
13557
13558   M (INTERFACE_NAME_RENUMBER, mp);
13559
13560   mp->sw_if_index = ntohl (sw_if_index);
13561   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13562
13563   S (mp);
13564   W (ret);
13565   return ret;
13566 }
13567
13568 static int
13569 api_want_ip4_arp_events (vat_main_t * vam)
13570 {
13571   unformat_input_t *line_input = vam->input;
13572   vl_api_want_ip4_arp_events_t *mp;
13573   ip4_address_t address;
13574   int address_set = 0;
13575   u32 enable_disable = 1;
13576   int ret;
13577
13578   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13581         address_set = 1;
13582       else if (unformat (line_input, "del"))
13583         enable_disable = 0;
13584       else
13585         break;
13586     }
13587
13588   if (address_set == 0)
13589     {
13590       errmsg ("missing addresses");
13591       return -99;
13592     }
13593
13594   M (WANT_IP4_ARP_EVENTS, mp);
13595   mp->enable_disable = enable_disable;
13596   mp->pid = htonl (getpid ());
13597   mp->address = address.as_u32;
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_want_ip6_nd_events (vat_main_t * vam)
13606 {
13607   unformat_input_t *line_input = vam->input;
13608   vl_api_want_ip6_nd_events_t *mp;
13609   ip6_address_t address;
13610   int address_set = 0;
13611   u32 enable_disable = 1;
13612   int ret;
13613
13614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13615     {
13616       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13617         address_set = 1;
13618       else if (unformat (line_input, "del"))
13619         enable_disable = 0;
13620       else
13621         break;
13622     }
13623
13624   if (address_set == 0)
13625     {
13626       errmsg ("missing addresses");
13627       return -99;
13628     }
13629
13630   M (WANT_IP6_ND_EVENTS, mp);
13631   mp->enable_disable = enable_disable;
13632   mp->pid = htonl (getpid ());
13633   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13634
13635   S (mp);
13636   W (ret);
13637   return ret;
13638 }
13639
13640 static int
13641 api_want_l2_macs_events (vat_main_t * vam)
13642 {
13643   unformat_input_t *line_input = vam->input;
13644   vl_api_want_l2_macs_events_t *mp;
13645   u8 enable_disable = 1;
13646   u32 scan_delay = 0;
13647   u32 max_macs_in_event = 0;
13648   u32 learn_limit = 0;
13649   int ret;
13650
13651   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13652     {
13653       if (unformat (line_input, "learn-limit %d", &learn_limit))
13654         ;
13655       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13656         ;
13657       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13658         ;
13659       else if (unformat (line_input, "disable"))
13660         enable_disable = 0;
13661       else
13662         break;
13663     }
13664
13665   M (WANT_L2_MACS_EVENTS, mp);
13666   mp->enable_disable = enable_disable;
13667   mp->pid = htonl (getpid ());
13668   mp->learn_limit = htonl (learn_limit);
13669   mp->scan_delay = (u8) scan_delay;
13670   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13671   S (mp);
13672   W (ret);
13673   return ret;
13674 }
13675
13676 static int
13677 api_input_acl_set_interface (vat_main_t * vam)
13678 {
13679   unformat_input_t *i = vam->input;
13680   vl_api_input_acl_set_interface_t *mp;
13681   u32 sw_if_index;
13682   int sw_if_index_set;
13683   u32 ip4_table_index = ~0;
13684   u32 ip6_table_index = ~0;
13685   u32 l2_table_index = ~0;
13686   u8 is_add = 1;
13687   int ret;
13688
13689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13690     {
13691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13692         sw_if_index_set = 1;
13693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13694         sw_if_index_set = 1;
13695       else if (unformat (i, "del"))
13696         is_add = 0;
13697       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13698         ;
13699       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13700         ;
13701       else if (unformat (i, "l2-table %d", &l2_table_index))
13702         ;
13703       else
13704         {
13705           clib_warning ("parse error '%U'", format_unformat_error, i);
13706           return -99;
13707         }
13708     }
13709
13710   if (sw_if_index_set == 0)
13711     {
13712       errmsg ("missing interface name or sw_if_index");
13713       return -99;
13714     }
13715
13716   M (INPUT_ACL_SET_INTERFACE, mp);
13717
13718   mp->sw_if_index = ntohl (sw_if_index);
13719   mp->ip4_table_index = ntohl (ip4_table_index);
13720   mp->ip6_table_index = ntohl (ip6_table_index);
13721   mp->l2_table_index = ntohl (l2_table_index);
13722   mp->is_add = is_add;
13723
13724   S (mp);
13725   W (ret);
13726   return ret;
13727 }
13728
13729 static int
13730 api_ip_address_dump (vat_main_t * vam)
13731 {
13732   unformat_input_t *i = vam->input;
13733   vl_api_ip_address_dump_t *mp;
13734   vl_api_control_ping_t *mp_ping;
13735   u32 sw_if_index = ~0;
13736   u8 sw_if_index_set = 0;
13737   u8 ipv4_set = 0;
13738   u8 ipv6_set = 0;
13739   int ret;
13740
13741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13742     {
13743       if (unformat (i, "sw_if_index %d", &sw_if_index))
13744         sw_if_index_set = 1;
13745       else
13746         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13747         sw_if_index_set = 1;
13748       else if (unformat (i, "ipv4"))
13749         ipv4_set = 1;
13750       else if (unformat (i, "ipv6"))
13751         ipv6_set = 1;
13752       else
13753         break;
13754     }
13755
13756   if (ipv4_set && ipv6_set)
13757     {
13758       errmsg ("ipv4 and ipv6 flags cannot be both set");
13759       return -99;
13760     }
13761
13762   if ((!ipv4_set) && (!ipv6_set))
13763     {
13764       errmsg ("no ipv4 nor ipv6 flag set");
13765       return -99;
13766     }
13767
13768   if (sw_if_index_set == 0)
13769     {
13770       errmsg ("missing interface name or sw_if_index");
13771       return -99;
13772     }
13773
13774   vam->current_sw_if_index = sw_if_index;
13775   vam->is_ipv6 = ipv6_set;
13776
13777   M (IP_ADDRESS_DUMP, mp);
13778   mp->sw_if_index = ntohl (sw_if_index);
13779   mp->is_ipv6 = ipv6_set;
13780   S (mp);
13781
13782   /* Use a control ping for synchronization */
13783   MPING (CONTROL_PING, mp_ping);
13784   S (mp_ping);
13785
13786   W (ret);
13787   return ret;
13788 }
13789
13790 static int
13791 api_ip_dump (vat_main_t * vam)
13792 {
13793   vl_api_ip_dump_t *mp;
13794   vl_api_control_ping_t *mp_ping;
13795   unformat_input_t *in = vam->input;
13796   int ipv4_set = 0;
13797   int ipv6_set = 0;
13798   int is_ipv6;
13799   int i;
13800   int ret;
13801
13802   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13803     {
13804       if (unformat (in, "ipv4"))
13805         ipv4_set = 1;
13806       else if (unformat (in, "ipv6"))
13807         ipv6_set = 1;
13808       else
13809         break;
13810     }
13811
13812   if (ipv4_set && ipv6_set)
13813     {
13814       errmsg ("ipv4 and ipv6 flags cannot be both set");
13815       return -99;
13816     }
13817
13818   if ((!ipv4_set) && (!ipv6_set))
13819     {
13820       errmsg ("no ipv4 nor ipv6 flag set");
13821       return -99;
13822     }
13823
13824   is_ipv6 = ipv6_set;
13825   vam->is_ipv6 = is_ipv6;
13826
13827   /* free old data */
13828   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13829     {
13830       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13831     }
13832   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13833
13834   M (IP_DUMP, mp);
13835   mp->is_ipv6 = ipv6_set;
13836   S (mp);
13837
13838   /* Use a control ping for synchronization */
13839   MPING (CONTROL_PING, mp_ping);
13840   S (mp_ping);
13841
13842   W (ret);
13843   return ret;
13844 }
13845
13846 static int
13847 api_ipsec_spd_add_del (vat_main_t * vam)
13848 {
13849   unformat_input_t *i = vam->input;
13850   vl_api_ipsec_spd_add_del_t *mp;
13851   u32 spd_id = ~0;
13852   u8 is_add = 1;
13853   int ret;
13854
13855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13856     {
13857       if (unformat (i, "spd_id %d", &spd_id))
13858         ;
13859       else if (unformat (i, "del"))
13860         is_add = 0;
13861       else
13862         {
13863           clib_warning ("parse error '%U'", format_unformat_error, i);
13864           return -99;
13865         }
13866     }
13867   if (spd_id == ~0)
13868     {
13869       errmsg ("spd_id must be set");
13870       return -99;
13871     }
13872
13873   M (IPSEC_SPD_ADD_DEL, mp);
13874
13875   mp->spd_id = ntohl (spd_id);
13876   mp->is_add = is_add;
13877
13878   S (mp);
13879   W (ret);
13880   return ret;
13881 }
13882
13883 static int
13884 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13885 {
13886   unformat_input_t *i = vam->input;
13887   vl_api_ipsec_interface_add_del_spd_t *mp;
13888   u32 sw_if_index;
13889   u8 sw_if_index_set = 0;
13890   u32 spd_id = (u32) ~ 0;
13891   u8 is_add = 1;
13892   int ret;
13893
13894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13895     {
13896       if (unformat (i, "del"))
13897         is_add = 0;
13898       else if (unformat (i, "spd_id %d", &spd_id))
13899         ;
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, "sw_if_index %d", &sw_if_index))
13904         sw_if_index_set = 1;
13905       else
13906         {
13907           clib_warning ("parse error '%U'", format_unformat_error, i);
13908           return -99;
13909         }
13910
13911     }
13912
13913   if (spd_id == (u32) ~ 0)
13914     {
13915       errmsg ("spd_id must be set");
13916       return -99;
13917     }
13918
13919   if (sw_if_index_set == 0)
13920     {
13921       errmsg ("missing interface name or sw_if_index");
13922       return -99;
13923     }
13924
13925   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13926
13927   mp->spd_id = ntohl (spd_id);
13928   mp->sw_if_index = ntohl (sw_if_index);
13929   mp->is_add = is_add;
13930
13931   S (mp);
13932   W (ret);
13933   return ret;
13934 }
13935
13936 static int
13937 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13938 {
13939   unformat_input_t *i = vam->input;
13940   vl_api_ipsec_spd_add_del_entry_t *mp;
13941   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13942   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13943   i32 priority = 0;
13944   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13945   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13946   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13947   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13948   int ret;
13949
13950   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13951   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13952   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13953   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13954   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13955   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13956
13957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (i, "del"))
13960         is_add = 0;
13961       if (unformat (i, "outbound"))
13962         is_outbound = 1;
13963       if (unformat (i, "inbound"))
13964         is_outbound = 0;
13965       else if (unformat (i, "spd_id %d", &spd_id))
13966         ;
13967       else if (unformat (i, "sa_id %d", &sa_id))
13968         ;
13969       else if (unformat (i, "priority %d", &priority))
13970         ;
13971       else if (unformat (i, "protocol %d", &protocol))
13972         ;
13973       else if (unformat (i, "lport_start %d", &lport_start))
13974         ;
13975       else if (unformat (i, "lport_stop %d", &lport_stop))
13976         ;
13977       else if (unformat (i, "rport_start %d", &rport_start))
13978         ;
13979       else if (unformat (i, "rport_stop %d", &rport_stop))
13980         ;
13981       else
13982         if (unformat
13983             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13984         {
13985           is_ipv6 = 0;
13986           is_ip_any = 0;
13987         }
13988       else
13989         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13990         {
13991           is_ipv6 = 0;
13992           is_ip_any = 0;
13993         }
13994       else
13995         if (unformat
13996             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13997         {
13998           is_ipv6 = 0;
13999           is_ip_any = 0;
14000         }
14001       else
14002         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14003         {
14004           is_ipv6 = 0;
14005           is_ip_any = 0;
14006         }
14007       else
14008         if (unformat
14009             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14010         {
14011           is_ipv6 = 1;
14012           is_ip_any = 0;
14013         }
14014       else
14015         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14016         {
14017           is_ipv6 = 1;
14018           is_ip_any = 0;
14019         }
14020       else
14021         if (unformat
14022             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14023         {
14024           is_ipv6 = 1;
14025           is_ip_any = 0;
14026         }
14027       else
14028         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14029         {
14030           is_ipv6 = 1;
14031           is_ip_any = 0;
14032         }
14033       else
14034         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14035         {
14036           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14037             {
14038               clib_warning ("unsupported action: 'resolve'");
14039               return -99;
14040             }
14041         }
14042       else
14043         {
14044           clib_warning ("parse error '%U'", format_unformat_error, i);
14045           return -99;
14046         }
14047
14048     }
14049
14050   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14051
14052   mp->spd_id = ntohl (spd_id);
14053   mp->priority = ntohl (priority);
14054   mp->is_outbound = is_outbound;
14055
14056   mp->is_ipv6 = is_ipv6;
14057   if (is_ipv6 || is_ip_any)
14058     {
14059       clib_memcpy (mp->remote_address_start, &raddr6_start,
14060                    sizeof (ip6_address_t));
14061       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14062                    sizeof (ip6_address_t));
14063       clib_memcpy (mp->local_address_start, &laddr6_start,
14064                    sizeof (ip6_address_t));
14065       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14066                    sizeof (ip6_address_t));
14067     }
14068   else
14069     {
14070       clib_memcpy (mp->remote_address_start, &raddr4_start,
14071                    sizeof (ip4_address_t));
14072       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14073                    sizeof (ip4_address_t));
14074       clib_memcpy (mp->local_address_start, &laddr4_start,
14075                    sizeof (ip4_address_t));
14076       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14077                    sizeof (ip4_address_t));
14078     }
14079   mp->protocol = (u8) protocol;
14080   mp->local_port_start = ntohs ((u16) lport_start);
14081   mp->local_port_stop = ntohs ((u16) lport_stop);
14082   mp->remote_port_start = ntohs ((u16) rport_start);
14083   mp->remote_port_stop = ntohs ((u16) rport_stop);
14084   mp->policy = (u8) policy;
14085   mp->sa_id = ntohl (sa_id);
14086   mp->is_add = is_add;
14087   mp->is_ip_any = is_ip_any;
14088   S (mp);
14089   W (ret);
14090   return ret;
14091 }
14092
14093 static int
14094 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14095 {
14096   unformat_input_t *i = vam->input;
14097   vl_api_ipsec_sad_add_del_entry_t *mp;
14098   u32 sad_id = 0, spi = 0;
14099   u8 *ck = 0, *ik = 0;
14100   u8 is_add = 1;
14101
14102   u8 protocol = IPSEC_PROTOCOL_AH;
14103   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14104   u32 crypto_alg = 0, integ_alg = 0;
14105   ip4_address_t tun_src4;
14106   ip4_address_t tun_dst4;
14107   ip6_address_t tun_src6;
14108   ip6_address_t tun_dst6;
14109   int ret;
14110
14111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (i, "del"))
14114         is_add = 0;
14115       else if (unformat (i, "sad_id %d", &sad_id))
14116         ;
14117       else if (unformat (i, "spi %d", &spi))
14118         ;
14119       else if (unformat (i, "esp"))
14120         protocol = IPSEC_PROTOCOL_ESP;
14121       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14122         {
14123           is_tunnel = 1;
14124           is_tunnel_ipv6 = 0;
14125         }
14126       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14127         {
14128           is_tunnel = 1;
14129           is_tunnel_ipv6 = 0;
14130         }
14131       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14132         {
14133           is_tunnel = 1;
14134           is_tunnel_ipv6 = 1;
14135         }
14136       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14137         {
14138           is_tunnel = 1;
14139           is_tunnel_ipv6 = 1;
14140         }
14141       else
14142         if (unformat
14143             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14144         {
14145           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14146               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14147             {
14148               clib_warning ("unsupported crypto-alg: '%U'",
14149                             format_ipsec_crypto_alg, crypto_alg);
14150               return -99;
14151             }
14152         }
14153       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14154         ;
14155       else
14156         if (unformat
14157             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14158         {
14159           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14160               integ_alg >= IPSEC_INTEG_N_ALG)
14161             {
14162               clib_warning ("unsupported integ-alg: '%U'",
14163                             format_ipsec_integ_alg, integ_alg);
14164               return -99;
14165             }
14166         }
14167       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14168         ;
14169       else
14170         {
14171           clib_warning ("parse error '%U'", format_unformat_error, i);
14172           return -99;
14173         }
14174
14175     }
14176
14177   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14178
14179   mp->sad_id = ntohl (sad_id);
14180   mp->is_add = is_add;
14181   mp->protocol = protocol;
14182   mp->spi = ntohl (spi);
14183   mp->is_tunnel = is_tunnel;
14184   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14185   mp->crypto_algorithm = crypto_alg;
14186   mp->integrity_algorithm = integ_alg;
14187   mp->crypto_key_length = vec_len (ck);
14188   mp->integrity_key_length = vec_len (ik);
14189
14190   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14191     mp->crypto_key_length = sizeof (mp->crypto_key);
14192
14193   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14194     mp->integrity_key_length = sizeof (mp->integrity_key);
14195
14196   if (ck)
14197     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14198   if (ik)
14199     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14200
14201   if (is_tunnel)
14202     {
14203       if (is_tunnel_ipv6)
14204         {
14205           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14206                        sizeof (ip6_address_t));
14207           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14208                        sizeof (ip6_address_t));
14209         }
14210       else
14211         {
14212           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14213                        sizeof (ip4_address_t));
14214           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14215                        sizeof (ip4_address_t));
14216         }
14217     }
14218
14219   S (mp);
14220   W (ret);
14221   return ret;
14222 }
14223
14224 static int
14225 api_ipsec_sa_set_key (vat_main_t * vam)
14226 {
14227   unformat_input_t *i = vam->input;
14228   vl_api_ipsec_sa_set_key_t *mp;
14229   u32 sa_id;
14230   u8 *ck = 0, *ik = 0;
14231   int ret;
14232
14233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14234     {
14235       if (unformat (i, "sa_id %d", &sa_id))
14236         ;
14237       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14238         ;
14239       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14240         ;
14241       else
14242         {
14243           clib_warning ("parse error '%U'", format_unformat_error, i);
14244           return -99;
14245         }
14246     }
14247
14248   M (IPSEC_SA_SET_KEY, mp);
14249
14250   mp->sa_id = ntohl (sa_id);
14251   mp->crypto_key_length = vec_len (ck);
14252   mp->integrity_key_length = vec_len (ik);
14253
14254   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14255     mp->crypto_key_length = sizeof (mp->crypto_key);
14256
14257   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14258     mp->integrity_key_length = sizeof (mp->integrity_key);
14259
14260   if (ck)
14261     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14262   if (ik)
14263     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14264
14265   S (mp);
14266   W (ret);
14267   return ret;
14268 }
14269
14270 static int
14271 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14272 {
14273   unformat_input_t *i = vam->input;
14274   vl_api_ipsec_tunnel_if_add_del_t *mp;
14275   u32 local_spi = 0, remote_spi = 0;
14276   u32 crypto_alg = 0, integ_alg = 0;
14277   u8 *lck = NULL, *rck = NULL;
14278   u8 *lik = NULL, *rik = NULL;
14279   ip4_address_t local_ip = { {0} };
14280   ip4_address_t remote_ip = { {0} };
14281   u8 is_add = 1;
14282   u8 esn = 0;
14283   u8 anti_replay = 0;
14284   int ret;
14285
14286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14287     {
14288       if (unformat (i, "del"))
14289         is_add = 0;
14290       else if (unformat (i, "esn"))
14291         esn = 1;
14292       else if (unformat (i, "anti_replay"))
14293         anti_replay = 1;
14294       else if (unformat (i, "local_spi %d", &local_spi))
14295         ;
14296       else if (unformat (i, "remote_spi %d", &remote_spi))
14297         ;
14298       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14299         ;
14300       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14301         ;
14302       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14303         ;
14304       else
14305         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14306         ;
14307       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14308         ;
14309       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14310         ;
14311       else
14312         if (unformat
14313             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14314         {
14315           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14316               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14317             {
14318               errmsg ("unsupported crypto-alg: '%U'\n",
14319                       format_ipsec_crypto_alg, crypto_alg);
14320               return -99;
14321             }
14322         }
14323       else
14324         if (unformat
14325             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14326         {
14327           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14328               integ_alg >= IPSEC_INTEG_N_ALG)
14329             {
14330               errmsg ("unsupported integ-alg: '%U'\n",
14331                       format_ipsec_integ_alg, integ_alg);
14332               return -99;
14333             }
14334         }
14335       else
14336         {
14337           errmsg ("parse error '%U'\n", format_unformat_error, i);
14338           return -99;
14339         }
14340     }
14341
14342   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14343
14344   mp->is_add = is_add;
14345   mp->esn = esn;
14346   mp->anti_replay = anti_replay;
14347
14348   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14349   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14350
14351   mp->local_spi = htonl (local_spi);
14352   mp->remote_spi = htonl (remote_spi);
14353   mp->crypto_alg = (u8) crypto_alg;
14354
14355   mp->local_crypto_key_len = 0;
14356   if (lck)
14357     {
14358       mp->local_crypto_key_len = vec_len (lck);
14359       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14360         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14361       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14362     }
14363
14364   mp->remote_crypto_key_len = 0;
14365   if (rck)
14366     {
14367       mp->remote_crypto_key_len = vec_len (rck);
14368       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14369         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14370       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14371     }
14372
14373   mp->integ_alg = (u8) integ_alg;
14374
14375   mp->local_integ_key_len = 0;
14376   if (lik)
14377     {
14378       mp->local_integ_key_len = vec_len (lik);
14379       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14380         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14381       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14382     }
14383
14384   mp->remote_integ_key_len = 0;
14385   if (rik)
14386     {
14387       mp->remote_integ_key_len = vec_len (rik);
14388       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14389         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14390       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14391     }
14392
14393   S (mp);
14394   W (ret);
14395   return ret;
14396 }
14397
14398 static void
14399 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14400 {
14401   vat_main_t *vam = &vat_main;
14402
14403   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14404          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14405          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14406          "tunnel_src_addr %U tunnel_dst_addr %U "
14407          "salt %u seq_outbound %lu last_seq_inbound %lu "
14408          "replay_window %lu total_data_size %lu\n",
14409          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14410          mp->protocol,
14411          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14412          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14413          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14414          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14415          mp->tunnel_src_addr,
14416          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14417          mp->tunnel_dst_addr,
14418          ntohl (mp->salt),
14419          clib_net_to_host_u64 (mp->seq_outbound),
14420          clib_net_to_host_u64 (mp->last_seq_inbound),
14421          clib_net_to_host_u64 (mp->replay_window),
14422          clib_net_to_host_u64 (mp->total_data_size));
14423 }
14424
14425 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14426 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14427
14428 static void vl_api_ipsec_sa_details_t_handler_json
14429   (vl_api_ipsec_sa_details_t * mp)
14430 {
14431   vat_main_t *vam = &vat_main;
14432   vat_json_node_t *node = NULL;
14433   struct in_addr src_ip4, dst_ip4;
14434   struct in6_addr src_ip6, dst_ip6;
14435
14436   if (VAT_JSON_ARRAY != vam->json_tree.type)
14437     {
14438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14439       vat_json_init_array (&vam->json_tree);
14440     }
14441   node = vat_json_array_add (&vam->json_tree);
14442
14443   vat_json_init_object (node);
14444   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14445   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14446   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14447   vat_json_object_add_uint (node, "proto", mp->protocol);
14448   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14449   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14450   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14451   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14452   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14453   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14454   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14455                              mp->crypto_key_len);
14456   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14457                              mp->integ_key_len);
14458   if (mp->is_tunnel_ip6)
14459     {
14460       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14461       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14462       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14463       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14464     }
14465   else
14466     {
14467       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14468       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14469       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14470       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14471     }
14472   vat_json_object_add_uint (node, "replay_window",
14473                             clib_net_to_host_u64 (mp->replay_window));
14474   vat_json_object_add_uint (node, "total_data_size",
14475                             clib_net_to_host_u64 (mp->total_data_size));
14476
14477 }
14478
14479 static int
14480 api_ipsec_sa_dump (vat_main_t * vam)
14481 {
14482   unformat_input_t *i = vam->input;
14483   vl_api_ipsec_sa_dump_t *mp;
14484   vl_api_control_ping_t *mp_ping;
14485   u32 sa_id = ~0;
14486   int ret;
14487
14488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14489     {
14490       if (unformat (i, "sa_id %d", &sa_id))
14491         ;
14492       else
14493         {
14494           clib_warning ("parse error '%U'", format_unformat_error, i);
14495           return -99;
14496         }
14497     }
14498
14499   M (IPSEC_SA_DUMP, mp);
14500
14501   mp->sa_id = ntohl (sa_id);
14502
14503   S (mp);
14504
14505   /* Use a control ping for synchronization */
14506   M (CONTROL_PING, mp_ping);
14507   S (mp_ping);
14508
14509   W (ret);
14510   return ret;
14511 }
14512
14513 static int
14514 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14515 {
14516   unformat_input_t *i = vam->input;
14517   vl_api_ipsec_tunnel_if_set_key_t *mp;
14518   u32 sw_if_index = ~0;
14519   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14520   u8 *key = 0;
14521   u32 alg = ~0;
14522   int ret;
14523
14524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14525     {
14526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14527         ;
14528       else
14529         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14530         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14531       else
14532         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14533         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14534       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14535         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14536       else
14537         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14538         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14539       else if (unformat (i, "%U", unformat_hex_string, &key))
14540         ;
14541       else
14542         {
14543           clib_warning ("parse error '%U'", format_unformat_error, i);
14544           return -99;
14545         }
14546     }
14547
14548   if (sw_if_index == ~0)
14549     {
14550       errmsg ("interface must be specified");
14551       return -99;
14552     }
14553
14554   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14555     {
14556       errmsg ("key type must be specified");
14557       return -99;
14558     }
14559
14560   if (alg == ~0)
14561     {
14562       errmsg ("algorithm must be specified");
14563       return -99;
14564     }
14565
14566   if (vec_len (key) == 0)
14567     {
14568       errmsg ("key must be specified");
14569       return -99;
14570     }
14571
14572   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14573
14574   mp->sw_if_index = htonl (sw_if_index);
14575   mp->alg = alg;
14576   mp->key_type = key_type;
14577   mp->key_len = vec_len (key);
14578   clib_memcpy (mp->key, key, vec_len (key));
14579
14580   S (mp);
14581   W (ret);
14582
14583   return ret;
14584 }
14585
14586 static int
14587 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14588 {
14589   unformat_input_t *i = vam->input;
14590   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14591   u32 sw_if_index = ~0;
14592   u32 sa_id = ~0;
14593   u8 is_outbound = (u8) ~ 0;
14594   int ret;
14595
14596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14597     {
14598       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14599         ;
14600       else if (unformat (i, "sa_id %d", &sa_id))
14601         ;
14602       else if (unformat (i, "outbound"))
14603         is_outbound = 1;
14604       else if (unformat (i, "inbound"))
14605         is_outbound = 0;
14606       else
14607         {
14608           clib_warning ("parse error '%U'", format_unformat_error, i);
14609           return -99;
14610         }
14611     }
14612
14613   if (sw_if_index == ~0)
14614     {
14615       errmsg ("interface must be specified");
14616       return -99;
14617     }
14618
14619   if (sa_id == ~0)
14620     {
14621       errmsg ("SA ID must be specified");
14622       return -99;
14623     }
14624
14625   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14626
14627   mp->sw_if_index = htonl (sw_if_index);
14628   mp->sa_id = htonl (sa_id);
14629   mp->is_outbound = is_outbound;
14630
14631   S (mp);
14632   W (ret);
14633
14634   return ret;
14635 }
14636
14637 static int
14638 api_ikev2_profile_add_del (vat_main_t * vam)
14639 {
14640   unformat_input_t *i = vam->input;
14641   vl_api_ikev2_profile_add_del_t *mp;
14642   u8 is_add = 1;
14643   u8 *name = 0;
14644   int ret;
14645
14646   const char *valid_chars = "a-zA-Z0-9_";
14647
14648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14649     {
14650       if (unformat (i, "del"))
14651         is_add = 0;
14652       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14653         vec_add1 (name, 0);
14654       else
14655         {
14656           errmsg ("parse error '%U'", format_unformat_error, i);
14657           return -99;
14658         }
14659     }
14660
14661   if (!vec_len (name))
14662     {
14663       errmsg ("profile name must be specified");
14664       return -99;
14665     }
14666
14667   if (vec_len (name) > 64)
14668     {
14669       errmsg ("profile name too long");
14670       return -99;
14671     }
14672
14673   M (IKEV2_PROFILE_ADD_DEL, mp);
14674
14675   clib_memcpy (mp->name, name, vec_len (name));
14676   mp->is_add = is_add;
14677   vec_free (name);
14678
14679   S (mp);
14680   W (ret);
14681   return ret;
14682 }
14683
14684 static int
14685 api_ikev2_profile_set_auth (vat_main_t * vam)
14686 {
14687   unformat_input_t *i = vam->input;
14688   vl_api_ikev2_profile_set_auth_t *mp;
14689   u8 *name = 0;
14690   u8 *data = 0;
14691   u32 auth_method = 0;
14692   u8 is_hex = 0;
14693   int ret;
14694
14695   const char *valid_chars = "a-zA-Z0-9_";
14696
14697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14700         vec_add1 (name, 0);
14701       else if (unformat (i, "auth_method %U",
14702                          unformat_ikev2_auth_method, &auth_method))
14703         ;
14704       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14705         is_hex = 1;
14706       else if (unformat (i, "auth_data %v", &data))
14707         ;
14708       else
14709         {
14710           errmsg ("parse error '%U'", format_unformat_error, i);
14711           return -99;
14712         }
14713     }
14714
14715   if (!vec_len (name))
14716     {
14717       errmsg ("profile name must be specified");
14718       return -99;
14719     }
14720
14721   if (vec_len (name) > 64)
14722     {
14723       errmsg ("profile name too long");
14724       return -99;
14725     }
14726
14727   if (!vec_len (data))
14728     {
14729       errmsg ("auth_data must be specified");
14730       return -99;
14731     }
14732
14733   if (!auth_method)
14734     {
14735       errmsg ("auth_method must be specified");
14736       return -99;
14737     }
14738
14739   M (IKEV2_PROFILE_SET_AUTH, mp);
14740
14741   mp->is_hex = is_hex;
14742   mp->auth_method = (u8) auth_method;
14743   mp->data_len = vec_len (data);
14744   clib_memcpy (mp->name, name, vec_len (name));
14745   clib_memcpy (mp->data, data, vec_len (data));
14746   vec_free (name);
14747   vec_free (data);
14748
14749   S (mp);
14750   W (ret);
14751   return ret;
14752 }
14753
14754 static int
14755 api_ikev2_profile_set_id (vat_main_t * vam)
14756 {
14757   unformat_input_t *i = vam->input;
14758   vl_api_ikev2_profile_set_id_t *mp;
14759   u8 *name = 0;
14760   u8 *data = 0;
14761   u8 is_local = 0;
14762   u32 id_type = 0;
14763   ip4_address_t ip4;
14764   int ret;
14765
14766   const char *valid_chars = "a-zA-Z0-9_";
14767
14768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14769     {
14770       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14771         vec_add1 (name, 0);
14772       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14773         ;
14774       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14775         {
14776           data = vec_new (u8, 4);
14777           clib_memcpy (data, ip4.as_u8, 4);
14778         }
14779       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14780         ;
14781       else if (unformat (i, "id_data %v", &data))
14782         ;
14783       else if (unformat (i, "local"))
14784         is_local = 1;
14785       else if (unformat (i, "remote"))
14786         is_local = 0;
14787       else
14788         {
14789           errmsg ("parse error '%U'", format_unformat_error, i);
14790           return -99;
14791         }
14792     }
14793
14794   if (!vec_len (name))
14795     {
14796       errmsg ("profile name must be specified");
14797       return -99;
14798     }
14799
14800   if (vec_len (name) > 64)
14801     {
14802       errmsg ("profile name too long");
14803       return -99;
14804     }
14805
14806   if (!vec_len (data))
14807     {
14808       errmsg ("id_data must be specified");
14809       return -99;
14810     }
14811
14812   if (!id_type)
14813     {
14814       errmsg ("id_type must be specified");
14815       return -99;
14816     }
14817
14818   M (IKEV2_PROFILE_SET_ID, mp);
14819
14820   mp->is_local = is_local;
14821   mp->id_type = (u8) id_type;
14822   mp->data_len = vec_len (data);
14823   clib_memcpy (mp->name, name, vec_len (name));
14824   clib_memcpy (mp->data, data, vec_len (data));
14825   vec_free (name);
14826   vec_free (data);
14827
14828   S (mp);
14829   W (ret);
14830   return ret;
14831 }
14832
14833 static int
14834 api_ikev2_profile_set_ts (vat_main_t * vam)
14835 {
14836   unformat_input_t *i = vam->input;
14837   vl_api_ikev2_profile_set_ts_t *mp;
14838   u8 *name = 0;
14839   u8 is_local = 0;
14840   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14841   ip4_address_t start_addr, end_addr;
14842
14843   const char *valid_chars = "a-zA-Z0-9_";
14844   int ret;
14845
14846   start_addr.as_u32 = 0;
14847   end_addr.as_u32 = (u32) ~ 0;
14848
14849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14850     {
14851       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14852         vec_add1 (name, 0);
14853       else if (unformat (i, "protocol %d", &proto))
14854         ;
14855       else if (unformat (i, "start_port %d", &start_port))
14856         ;
14857       else if (unformat (i, "end_port %d", &end_port))
14858         ;
14859       else
14860         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14861         ;
14862       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14863         ;
14864       else if (unformat (i, "local"))
14865         is_local = 1;
14866       else if (unformat (i, "remote"))
14867         is_local = 0;
14868       else
14869         {
14870           errmsg ("parse error '%U'", format_unformat_error, i);
14871           return -99;
14872         }
14873     }
14874
14875   if (!vec_len (name))
14876     {
14877       errmsg ("profile name must be specified");
14878       return -99;
14879     }
14880
14881   if (vec_len (name) > 64)
14882     {
14883       errmsg ("profile name too long");
14884       return -99;
14885     }
14886
14887   M (IKEV2_PROFILE_SET_TS, mp);
14888
14889   mp->is_local = is_local;
14890   mp->proto = (u8) proto;
14891   mp->start_port = (u16) start_port;
14892   mp->end_port = (u16) end_port;
14893   mp->start_addr = start_addr.as_u32;
14894   mp->end_addr = end_addr.as_u32;
14895   clib_memcpy (mp->name, name, vec_len (name));
14896   vec_free (name);
14897
14898   S (mp);
14899   W (ret);
14900   return ret;
14901 }
14902
14903 static int
14904 api_ikev2_set_local_key (vat_main_t * vam)
14905 {
14906   unformat_input_t *i = vam->input;
14907   vl_api_ikev2_set_local_key_t *mp;
14908   u8 *file = 0;
14909   int ret;
14910
14911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14912     {
14913       if (unformat (i, "file %v", &file))
14914         vec_add1 (file, 0);
14915       else
14916         {
14917           errmsg ("parse error '%U'", format_unformat_error, i);
14918           return -99;
14919         }
14920     }
14921
14922   if (!vec_len (file))
14923     {
14924       errmsg ("RSA key file must be specified");
14925       return -99;
14926     }
14927
14928   if (vec_len (file) > 256)
14929     {
14930       errmsg ("file name too long");
14931       return -99;
14932     }
14933
14934   M (IKEV2_SET_LOCAL_KEY, mp);
14935
14936   clib_memcpy (mp->key_file, file, vec_len (file));
14937   vec_free (file);
14938
14939   S (mp);
14940   W (ret);
14941   return ret;
14942 }
14943
14944 static int
14945 api_ikev2_set_responder (vat_main_t * vam)
14946 {
14947   unformat_input_t *i = vam->input;
14948   vl_api_ikev2_set_responder_t *mp;
14949   int ret;
14950   u8 *name = 0;
14951   u32 sw_if_index = ~0;
14952   ip4_address_t address;
14953
14954   const char *valid_chars = "a-zA-Z0-9_";
14955
14956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14957     {
14958       if (unformat
14959           (i, "%U interface %d address %U", unformat_token, valid_chars,
14960            &name, &sw_if_index, unformat_ip4_address, &address))
14961         vec_add1 (name, 0);
14962       else
14963         {
14964           errmsg ("parse error '%U'", format_unformat_error, i);
14965           return -99;
14966         }
14967     }
14968
14969   if (!vec_len (name))
14970     {
14971       errmsg ("profile name must be specified");
14972       return -99;
14973     }
14974
14975   if (vec_len (name) > 64)
14976     {
14977       errmsg ("profile name too long");
14978       return -99;
14979     }
14980
14981   M (IKEV2_SET_RESPONDER, mp);
14982
14983   clib_memcpy (mp->name, name, vec_len (name));
14984   vec_free (name);
14985
14986   mp->sw_if_index = sw_if_index;
14987   clib_memcpy (mp->address, &address, sizeof (address));
14988
14989   S (mp);
14990   W (ret);
14991   return ret;
14992 }
14993
14994 static int
14995 api_ikev2_set_ike_transforms (vat_main_t * vam)
14996 {
14997   unformat_input_t *i = vam->input;
14998   vl_api_ikev2_set_ike_transforms_t *mp;
14999   int ret;
15000   u8 *name = 0;
15001   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15002
15003   const char *valid_chars = "a-zA-Z0-9_";
15004
15005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15006     {
15007       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15008                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15009         vec_add1 (name, 0);
15010       else
15011         {
15012           errmsg ("parse error '%U'", format_unformat_error, i);
15013           return -99;
15014         }
15015     }
15016
15017   if (!vec_len (name))
15018     {
15019       errmsg ("profile name must be specified");
15020       return -99;
15021     }
15022
15023   if (vec_len (name) > 64)
15024     {
15025       errmsg ("profile name too long");
15026       return -99;
15027     }
15028
15029   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15030
15031   clib_memcpy (mp->name, name, vec_len (name));
15032   vec_free (name);
15033   mp->crypto_alg = crypto_alg;
15034   mp->crypto_key_size = crypto_key_size;
15035   mp->integ_alg = integ_alg;
15036   mp->dh_group = dh_group;
15037
15038   S (mp);
15039   W (ret);
15040   return ret;
15041 }
15042
15043
15044 static int
15045 api_ikev2_set_esp_transforms (vat_main_t * vam)
15046 {
15047   unformat_input_t *i = vam->input;
15048   vl_api_ikev2_set_esp_transforms_t *mp;
15049   int ret;
15050   u8 *name = 0;
15051   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15052
15053   const char *valid_chars = "a-zA-Z0-9_";
15054
15055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15056     {
15057       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15058                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15059         vec_add1 (name, 0);
15060       else
15061         {
15062           errmsg ("parse error '%U'", format_unformat_error, i);
15063           return -99;
15064         }
15065     }
15066
15067   if (!vec_len (name))
15068     {
15069       errmsg ("profile name must be specified");
15070       return -99;
15071     }
15072
15073   if (vec_len (name) > 64)
15074     {
15075       errmsg ("profile name too long");
15076       return -99;
15077     }
15078
15079   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15080
15081   clib_memcpy (mp->name, name, vec_len (name));
15082   vec_free (name);
15083   mp->crypto_alg = crypto_alg;
15084   mp->crypto_key_size = crypto_key_size;
15085   mp->integ_alg = integ_alg;
15086   mp->dh_group = dh_group;
15087
15088   S (mp);
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15095 {
15096   unformat_input_t *i = vam->input;
15097   vl_api_ikev2_set_sa_lifetime_t *mp;
15098   int ret;
15099   u8 *name = 0;
15100   u64 lifetime, lifetime_maxdata;
15101   u32 lifetime_jitter, handover;
15102
15103   const char *valid_chars = "a-zA-Z0-9_";
15104
15105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15106     {
15107       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15108                     &lifetime, &lifetime_jitter, &handover,
15109                     &lifetime_maxdata))
15110         vec_add1 (name, 0);
15111       else
15112         {
15113           errmsg ("parse error '%U'", format_unformat_error, i);
15114           return -99;
15115         }
15116     }
15117
15118   if (!vec_len (name))
15119     {
15120       errmsg ("profile name must be specified");
15121       return -99;
15122     }
15123
15124   if (vec_len (name) > 64)
15125     {
15126       errmsg ("profile name too long");
15127       return -99;
15128     }
15129
15130   M (IKEV2_SET_SA_LIFETIME, mp);
15131
15132   clib_memcpy (mp->name, name, vec_len (name));
15133   vec_free (name);
15134   mp->lifetime = lifetime;
15135   mp->lifetime_jitter = lifetime_jitter;
15136   mp->handover = handover;
15137   mp->lifetime_maxdata = lifetime_maxdata;
15138
15139   S (mp);
15140   W (ret);
15141   return ret;
15142 }
15143
15144 static int
15145 api_ikev2_initiate_sa_init (vat_main_t * vam)
15146 {
15147   unformat_input_t *i = vam->input;
15148   vl_api_ikev2_initiate_sa_init_t *mp;
15149   int ret;
15150   u8 *name = 0;
15151
15152   const char *valid_chars = "a-zA-Z0-9_";
15153
15154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15155     {
15156       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15157         vec_add1 (name, 0);
15158       else
15159         {
15160           errmsg ("parse error '%U'", format_unformat_error, i);
15161           return -99;
15162         }
15163     }
15164
15165   if (!vec_len (name))
15166     {
15167       errmsg ("profile name must be specified");
15168       return -99;
15169     }
15170
15171   if (vec_len (name) > 64)
15172     {
15173       errmsg ("profile name too long");
15174       return -99;
15175     }
15176
15177   M (IKEV2_INITIATE_SA_INIT, mp);
15178
15179   clib_memcpy (mp->name, name, vec_len (name));
15180   vec_free (name);
15181
15182   S (mp);
15183   W (ret);
15184   return ret;
15185 }
15186
15187 static int
15188 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15189 {
15190   unformat_input_t *i = vam->input;
15191   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15192   int ret;
15193   u64 ispi;
15194
15195
15196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15197     {
15198       if (unformat (i, "%lx", &ispi))
15199         ;
15200       else
15201         {
15202           errmsg ("parse error '%U'", format_unformat_error, i);
15203           return -99;
15204         }
15205     }
15206
15207   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15208
15209   mp->ispi = ispi;
15210
15211   S (mp);
15212   W (ret);
15213   return ret;
15214 }
15215
15216 static int
15217 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15218 {
15219   unformat_input_t *i = vam->input;
15220   vl_api_ikev2_initiate_del_child_sa_t *mp;
15221   int ret;
15222   u32 ispi;
15223
15224
15225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (i, "%x", &ispi))
15228         ;
15229       else
15230         {
15231           errmsg ("parse error '%U'", format_unformat_error, i);
15232           return -99;
15233         }
15234     }
15235
15236   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15237
15238   mp->ispi = ispi;
15239
15240   S (mp);
15241   W (ret);
15242   return ret;
15243 }
15244
15245 static int
15246 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15247 {
15248   unformat_input_t *i = vam->input;
15249   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15250   int ret;
15251   u32 ispi;
15252
15253
15254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15255     {
15256       if (unformat (i, "%x", &ispi))
15257         ;
15258       else
15259         {
15260           errmsg ("parse error '%U'", format_unformat_error, i);
15261           return -99;
15262         }
15263     }
15264
15265   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15266
15267   mp->ispi = ispi;
15268
15269   S (mp);
15270   W (ret);
15271   return ret;
15272 }
15273
15274 /*
15275  * MAP
15276  */
15277 static int
15278 api_map_add_domain (vat_main_t * vam)
15279 {
15280   unformat_input_t *i = vam->input;
15281   vl_api_map_add_domain_t *mp;
15282
15283   ip4_address_t ip4_prefix;
15284   ip6_address_t ip6_prefix;
15285   ip6_address_t ip6_src;
15286   u32 num_m_args = 0;
15287   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15288     0, psid_length = 0;
15289   u8 is_translation = 0;
15290   u32 mtu = 0;
15291   u32 ip6_src_len = 128;
15292   int ret;
15293
15294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15295     {
15296       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15297                     &ip4_prefix, &ip4_prefix_len))
15298         num_m_args++;
15299       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15300                          &ip6_prefix, &ip6_prefix_len))
15301         num_m_args++;
15302       else
15303         if (unformat
15304             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15305              &ip6_src_len))
15306         num_m_args++;
15307       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15308         num_m_args++;
15309       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15310         num_m_args++;
15311       else if (unformat (i, "psid-offset %d", &psid_offset))
15312         num_m_args++;
15313       else if (unformat (i, "psid-len %d", &psid_length))
15314         num_m_args++;
15315       else if (unformat (i, "mtu %d", &mtu))
15316         num_m_args++;
15317       else if (unformat (i, "map-t"))
15318         is_translation = 1;
15319       else
15320         {
15321           clib_warning ("parse error '%U'", format_unformat_error, i);
15322           return -99;
15323         }
15324     }
15325
15326   if (num_m_args < 3)
15327     {
15328       errmsg ("mandatory argument(s) missing");
15329       return -99;
15330     }
15331
15332   /* Construct the API message */
15333   M (MAP_ADD_DOMAIN, mp);
15334
15335   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15336   mp->ip4_prefix_len = ip4_prefix_len;
15337
15338   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15339   mp->ip6_prefix_len = ip6_prefix_len;
15340
15341   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15342   mp->ip6_src_prefix_len = ip6_src_len;
15343
15344   mp->ea_bits_len = ea_bits_len;
15345   mp->psid_offset = psid_offset;
15346   mp->psid_length = psid_length;
15347   mp->is_translation = is_translation;
15348   mp->mtu = htons (mtu);
15349
15350   /* send it... */
15351   S (mp);
15352
15353   /* Wait for a reply, return good/bad news  */
15354   W (ret);
15355   return ret;
15356 }
15357
15358 static int
15359 api_map_del_domain (vat_main_t * vam)
15360 {
15361   unformat_input_t *i = vam->input;
15362   vl_api_map_del_domain_t *mp;
15363
15364   u32 num_m_args = 0;
15365   u32 index;
15366   int ret;
15367
15368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat (i, "index %d", &index))
15371         num_m_args++;
15372       else
15373         {
15374           clib_warning ("parse error '%U'", format_unformat_error, i);
15375           return -99;
15376         }
15377     }
15378
15379   if (num_m_args != 1)
15380     {
15381       errmsg ("mandatory argument(s) missing");
15382       return -99;
15383     }
15384
15385   /* Construct the API message */
15386   M (MAP_DEL_DOMAIN, mp);
15387
15388   mp->index = ntohl (index);
15389
15390   /* send it... */
15391   S (mp);
15392
15393   /* Wait for a reply, return good/bad news  */
15394   W (ret);
15395   return ret;
15396 }
15397
15398 static int
15399 api_map_add_del_rule (vat_main_t * vam)
15400 {
15401   unformat_input_t *i = vam->input;
15402   vl_api_map_add_del_rule_t *mp;
15403   u8 is_add = 1;
15404   ip6_address_t ip6_dst;
15405   u32 num_m_args = 0, index, psid = 0;
15406   int ret;
15407
15408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15409     {
15410       if (unformat (i, "index %d", &index))
15411         num_m_args++;
15412       else if (unformat (i, "psid %d", &psid))
15413         num_m_args++;
15414       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15415         num_m_args++;
15416       else if (unformat (i, "del"))
15417         {
15418           is_add = 0;
15419         }
15420       else
15421         {
15422           clib_warning ("parse error '%U'", format_unformat_error, i);
15423           return -99;
15424         }
15425     }
15426
15427   /* Construct the API message */
15428   M (MAP_ADD_DEL_RULE, mp);
15429
15430   mp->index = ntohl (index);
15431   mp->is_add = is_add;
15432   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15433   mp->psid = ntohs (psid);
15434
15435   /* send it... */
15436   S (mp);
15437
15438   /* Wait for a reply, return good/bad news  */
15439   W (ret);
15440   return ret;
15441 }
15442
15443 static int
15444 api_map_domain_dump (vat_main_t * vam)
15445 {
15446   vl_api_map_domain_dump_t *mp;
15447   vl_api_control_ping_t *mp_ping;
15448   int ret;
15449
15450   /* Construct the API message */
15451   M (MAP_DOMAIN_DUMP, mp);
15452
15453   /* send it... */
15454   S (mp);
15455
15456   /* Use a control ping for synchronization */
15457   MPING (CONTROL_PING, mp_ping);
15458   S (mp_ping);
15459
15460   W (ret);
15461   return ret;
15462 }
15463
15464 static int
15465 api_map_rule_dump (vat_main_t * vam)
15466 {
15467   unformat_input_t *i = vam->input;
15468   vl_api_map_rule_dump_t *mp;
15469   vl_api_control_ping_t *mp_ping;
15470   u32 domain_index = ~0;
15471   int ret;
15472
15473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15474     {
15475       if (unformat (i, "index %u", &domain_index))
15476         ;
15477       else
15478         break;
15479     }
15480
15481   if (domain_index == ~0)
15482     {
15483       clib_warning ("parse error: domain index expected");
15484       return -99;
15485     }
15486
15487   /* Construct the API message */
15488   M (MAP_RULE_DUMP, mp);
15489
15490   mp->domain_index = htonl (domain_index);
15491
15492   /* send it... */
15493   S (mp);
15494
15495   /* Use a control ping for synchronization */
15496   MPING (CONTROL_PING, mp_ping);
15497   S (mp_ping);
15498
15499   W (ret);
15500   return ret;
15501 }
15502
15503 static void vl_api_map_add_domain_reply_t_handler
15504   (vl_api_map_add_domain_reply_t * mp)
15505 {
15506   vat_main_t *vam = &vat_main;
15507   i32 retval = ntohl (mp->retval);
15508
15509   if (vam->async_mode)
15510     {
15511       vam->async_errors += (retval < 0);
15512     }
15513   else
15514     {
15515       vam->retval = retval;
15516       vam->result_ready = 1;
15517     }
15518 }
15519
15520 static void vl_api_map_add_domain_reply_t_handler_json
15521   (vl_api_map_add_domain_reply_t * mp)
15522 {
15523   vat_main_t *vam = &vat_main;
15524   vat_json_node_t node;
15525
15526   vat_json_init_object (&node);
15527   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15528   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15529
15530   vat_json_print (vam->ofp, &node);
15531   vat_json_free (&node);
15532
15533   vam->retval = ntohl (mp->retval);
15534   vam->result_ready = 1;
15535 }
15536
15537 static int
15538 api_get_first_msg_id (vat_main_t * vam)
15539 {
15540   vl_api_get_first_msg_id_t *mp;
15541   unformat_input_t *i = vam->input;
15542   u8 *name;
15543   u8 name_set = 0;
15544   int ret;
15545
15546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15547     {
15548       if (unformat (i, "client %s", &name))
15549         name_set = 1;
15550       else
15551         break;
15552     }
15553
15554   if (name_set == 0)
15555     {
15556       errmsg ("missing client name");
15557       return -99;
15558     }
15559   vec_add1 (name, 0);
15560
15561   if (vec_len (name) > 63)
15562     {
15563       errmsg ("client name too long");
15564       return -99;
15565     }
15566
15567   M (GET_FIRST_MSG_ID, mp);
15568   clib_memcpy (mp->name, name, vec_len (name));
15569   S (mp);
15570   W (ret);
15571   return ret;
15572 }
15573
15574 static int
15575 api_cop_interface_enable_disable (vat_main_t * vam)
15576 {
15577   unformat_input_t *line_input = vam->input;
15578   vl_api_cop_interface_enable_disable_t *mp;
15579   u32 sw_if_index = ~0;
15580   u8 enable_disable = 1;
15581   int ret;
15582
15583   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15584     {
15585       if (unformat (line_input, "disable"))
15586         enable_disable = 0;
15587       if (unformat (line_input, "enable"))
15588         enable_disable = 1;
15589       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15590                          vam, &sw_if_index))
15591         ;
15592       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15593         ;
15594       else
15595         break;
15596     }
15597
15598   if (sw_if_index == ~0)
15599     {
15600       errmsg ("missing interface name or sw_if_index");
15601       return -99;
15602     }
15603
15604   /* Construct the API message */
15605   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15606   mp->sw_if_index = ntohl (sw_if_index);
15607   mp->enable_disable = enable_disable;
15608
15609   /* send it... */
15610   S (mp);
15611   /* Wait for the reply */
15612   W (ret);
15613   return ret;
15614 }
15615
15616 static int
15617 api_cop_whitelist_enable_disable (vat_main_t * vam)
15618 {
15619   unformat_input_t *line_input = vam->input;
15620   vl_api_cop_whitelist_enable_disable_t *mp;
15621   u32 sw_if_index = ~0;
15622   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15623   u32 fib_id = 0;
15624   int ret;
15625
15626   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15627     {
15628       if (unformat (line_input, "ip4"))
15629         ip4 = 1;
15630       else if (unformat (line_input, "ip6"))
15631         ip6 = 1;
15632       else if (unformat (line_input, "default"))
15633         default_cop = 1;
15634       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15635                          vam, &sw_if_index))
15636         ;
15637       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15638         ;
15639       else if (unformat (line_input, "fib-id %d", &fib_id))
15640         ;
15641       else
15642         break;
15643     }
15644
15645   if (sw_if_index == ~0)
15646     {
15647       errmsg ("missing interface name or sw_if_index");
15648       return -99;
15649     }
15650
15651   /* Construct the API message */
15652   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15653   mp->sw_if_index = ntohl (sw_if_index);
15654   mp->fib_id = ntohl (fib_id);
15655   mp->ip4 = ip4;
15656   mp->ip6 = ip6;
15657   mp->default_cop = default_cop;
15658
15659   /* send it... */
15660   S (mp);
15661   /* Wait for the reply */
15662   W (ret);
15663   return ret;
15664 }
15665
15666 static int
15667 api_get_node_graph (vat_main_t * vam)
15668 {
15669   vl_api_get_node_graph_t *mp;
15670   int ret;
15671
15672   M (GET_NODE_GRAPH, mp);
15673
15674   /* send it... */
15675   S (mp);
15676   /* Wait for the reply */
15677   W (ret);
15678   return ret;
15679 }
15680
15681 /* *INDENT-OFF* */
15682 /** Used for parsing LISP eids */
15683 typedef CLIB_PACKED(struct{
15684   u8 addr[16];   /**< eid address */
15685   u32 len;       /**< prefix length if IP */
15686   u8 type;      /**< type of eid */
15687 }) lisp_eid_vat_t;
15688 /* *INDENT-ON* */
15689
15690 static uword
15691 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15692 {
15693   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15694
15695   memset (a, 0, sizeof (a[0]));
15696
15697   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15698     {
15699       a->type = 0;              /* ipv4 type */
15700     }
15701   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15702     {
15703       a->type = 1;              /* ipv6 type */
15704     }
15705   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15706     {
15707       a->type = 2;              /* mac type */
15708     }
15709   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15710     {
15711       a->type = 3;              /* NSH type */
15712       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15713       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15714     }
15715   else
15716     {
15717       return 0;
15718     }
15719
15720   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15721     {
15722       return 0;
15723     }
15724
15725   return 1;
15726 }
15727
15728 static int
15729 lisp_eid_size_vat (u8 type)
15730 {
15731   switch (type)
15732     {
15733     case 0:
15734       return 4;
15735     case 1:
15736       return 16;
15737     case 2:
15738       return 6;
15739     case 3:
15740       return 5;
15741     }
15742   return 0;
15743 }
15744
15745 static void
15746 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15747 {
15748   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15749 }
15750
15751 static int
15752 api_one_add_del_locator_set (vat_main_t * vam)
15753 {
15754   unformat_input_t *input = vam->input;
15755   vl_api_one_add_del_locator_set_t *mp;
15756   u8 is_add = 1;
15757   u8 *locator_set_name = NULL;
15758   u8 locator_set_name_set = 0;
15759   vl_api_local_locator_t locator, *locators = 0;
15760   u32 sw_if_index, priority, weight;
15761   u32 data_len = 0;
15762
15763   int ret;
15764   /* Parse args required to build the message */
15765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15766     {
15767       if (unformat (input, "del"))
15768         {
15769           is_add = 0;
15770         }
15771       else if (unformat (input, "locator-set %s", &locator_set_name))
15772         {
15773           locator_set_name_set = 1;
15774         }
15775       else if (unformat (input, "sw_if_index %u p %u w %u",
15776                          &sw_if_index, &priority, &weight))
15777         {
15778           locator.sw_if_index = htonl (sw_if_index);
15779           locator.priority = priority;
15780           locator.weight = weight;
15781           vec_add1 (locators, locator);
15782         }
15783       else
15784         if (unformat
15785             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15786              &sw_if_index, &priority, &weight))
15787         {
15788           locator.sw_if_index = htonl (sw_if_index);
15789           locator.priority = priority;
15790           locator.weight = weight;
15791           vec_add1 (locators, locator);
15792         }
15793       else
15794         break;
15795     }
15796
15797   if (locator_set_name_set == 0)
15798     {
15799       errmsg ("missing locator-set name");
15800       vec_free (locators);
15801       return -99;
15802     }
15803
15804   if (vec_len (locator_set_name) > 64)
15805     {
15806       errmsg ("locator-set name too long");
15807       vec_free (locator_set_name);
15808       vec_free (locators);
15809       return -99;
15810     }
15811   vec_add1 (locator_set_name, 0);
15812
15813   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15814
15815   /* Construct the API message */
15816   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15817
15818   mp->is_add = is_add;
15819   clib_memcpy (mp->locator_set_name, locator_set_name,
15820                vec_len (locator_set_name));
15821   vec_free (locator_set_name);
15822
15823   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15824   if (locators)
15825     clib_memcpy (mp->locators, locators, data_len);
15826   vec_free (locators);
15827
15828   /* send it... */
15829   S (mp);
15830
15831   /* Wait for a reply... */
15832   W (ret);
15833   return ret;
15834 }
15835
15836 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15837
15838 static int
15839 api_one_add_del_locator (vat_main_t * vam)
15840 {
15841   unformat_input_t *input = vam->input;
15842   vl_api_one_add_del_locator_t *mp;
15843   u32 tmp_if_index = ~0;
15844   u32 sw_if_index = ~0;
15845   u8 sw_if_index_set = 0;
15846   u8 sw_if_index_if_name_set = 0;
15847   u32 priority = ~0;
15848   u8 priority_set = 0;
15849   u32 weight = ~0;
15850   u8 weight_set = 0;
15851   u8 is_add = 1;
15852   u8 *locator_set_name = NULL;
15853   u8 locator_set_name_set = 0;
15854   int ret;
15855
15856   /* Parse args required to build the message */
15857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15858     {
15859       if (unformat (input, "del"))
15860         {
15861           is_add = 0;
15862         }
15863       else if (unformat (input, "locator-set %s", &locator_set_name))
15864         {
15865           locator_set_name_set = 1;
15866         }
15867       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15868                          &tmp_if_index))
15869         {
15870           sw_if_index_if_name_set = 1;
15871           sw_if_index = tmp_if_index;
15872         }
15873       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15874         {
15875           sw_if_index_set = 1;
15876           sw_if_index = tmp_if_index;
15877         }
15878       else if (unformat (input, "p %d", &priority))
15879         {
15880           priority_set = 1;
15881         }
15882       else if (unformat (input, "w %d", &weight))
15883         {
15884           weight_set = 1;
15885         }
15886       else
15887         break;
15888     }
15889
15890   if (locator_set_name_set == 0)
15891     {
15892       errmsg ("missing locator-set name");
15893       return -99;
15894     }
15895
15896   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15897     {
15898       errmsg ("missing sw_if_index");
15899       vec_free (locator_set_name);
15900       return -99;
15901     }
15902
15903   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15904     {
15905       errmsg ("cannot use both params interface name and sw_if_index");
15906       vec_free (locator_set_name);
15907       return -99;
15908     }
15909
15910   if (priority_set == 0)
15911     {
15912       errmsg ("missing locator-set priority");
15913       vec_free (locator_set_name);
15914       return -99;
15915     }
15916
15917   if (weight_set == 0)
15918     {
15919       errmsg ("missing locator-set weight");
15920       vec_free (locator_set_name);
15921       return -99;
15922     }
15923
15924   if (vec_len (locator_set_name) > 64)
15925     {
15926       errmsg ("locator-set name too long");
15927       vec_free (locator_set_name);
15928       return -99;
15929     }
15930   vec_add1 (locator_set_name, 0);
15931
15932   /* Construct the API message */
15933   M (ONE_ADD_DEL_LOCATOR, mp);
15934
15935   mp->is_add = is_add;
15936   mp->sw_if_index = ntohl (sw_if_index);
15937   mp->priority = priority;
15938   mp->weight = weight;
15939   clib_memcpy (mp->locator_set_name, locator_set_name,
15940                vec_len (locator_set_name));
15941   vec_free (locator_set_name);
15942
15943   /* send it... */
15944   S (mp);
15945
15946   /* Wait for a reply... */
15947   W (ret);
15948   return ret;
15949 }
15950
15951 #define api_lisp_add_del_locator api_one_add_del_locator
15952
15953 uword
15954 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15955 {
15956   u32 *key_id = va_arg (*args, u32 *);
15957   u8 *s = 0;
15958
15959   if (unformat (input, "%s", &s))
15960     {
15961       if (!strcmp ((char *) s, "sha1"))
15962         key_id[0] = HMAC_SHA_1_96;
15963       else if (!strcmp ((char *) s, "sha256"))
15964         key_id[0] = HMAC_SHA_256_128;
15965       else
15966         {
15967           clib_warning ("invalid key_id: '%s'", s);
15968           key_id[0] = HMAC_NO_KEY;
15969         }
15970     }
15971   else
15972     return 0;
15973
15974   vec_free (s);
15975   return 1;
15976 }
15977
15978 static int
15979 api_one_add_del_local_eid (vat_main_t * vam)
15980 {
15981   unformat_input_t *input = vam->input;
15982   vl_api_one_add_del_local_eid_t *mp;
15983   u8 is_add = 1;
15984   u8 eid_set = 0;
15985   lisp_eid_vat_t _eid, *eid = &_eid;
15986   u8 *locator_set_name = 0;
15987   u8 locator_set_name_set = 0;
15988   u32 vni = 0;
15989   u16 key_id = 0;
15990   u8 *key = 0;
15991   int ret;
15992
15993   /* Parse args required to build the message */
15994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15995     {
15996       if (unformat (input, "del"))
15997         {
15998           is_add = 0;
15999         }
16000       else if (unformat (input, "vni %d", &vni))
16001         {
16002           ;
16003         }
16004       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16005         {
16006           eid_set = 1;
16007         }
16008       else if (unformat (input, "locator-set %s", &locator_set_name))
16009         {
16010           locator_set_name_set = 1;
16011         }
16012       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16013         ;
16014       else if (unformat (input, "secret-key %_%v%_", &key))
16015         ;
16016       else
16017         break;
16018     }
16019
16020   if (locator_set_name_set == 0)
16021     {
16022       errmsg ("missing locator-set name");
16023       return -99;
16024     }
16025
16026   if (0 == eid_set)
16027     {
16028       errmsg ("EID address not set!");
16029       vec_free (locator_set_name);
16030       return -99;
16031     }
16032
16033   if (key && (0 == key_id))
16034     {
16035       errmsg ("invalid key_id!");
16036       return -99;
16037     }
16038
16039   if (vec_len (key) > 64)
16040     {
16041       errmsg ("key too long");
16042       vec_free (key);
16043       return -99;
16044     }
16045
16046   if (vec_len (locator_set_name) > 64)
16047     {
16048       errmsg ("locator-set name too long");
16049       vec_free (locator_set_name);
16050       return -99;
16051     }
16052   vec_add1 (locator_set_name, 0);
16053
16054   /* Construct the API message */
16055   M (ONE_ADD_DEL_LOCAL_EID, mp);
16056
16057   mp->is_add = is_add;
16058   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16059   mp->eid_type = eid->type;
16060   mp->prefix_len = eid->len;
16061   mp->vni = clib_host_to_net_u32 (vni);
16062   mp->key_id = clib_host_to_net_u16 (key_id);
16063   clib_memcpy (mp->locator_set_name, locator_set_name,
16064                vec_len (locator_set_name));
16065   clib_memcpy (mp->key, key, vec_len (key));
16066
16067   vec_free (locator_set_name);
16068   vec_free (key);
16069
16070   /* send it... */
16071   S (mp);
16072
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16079
16080 static int
16081 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16082 {
16083   u32 dp_table = 0, vni = 0;;
16084   unformat_input_t *input = vam->input;
16085   vl_api_gpe_add_del_fwd_entry_t *mp;
16086   u8 is_add = 1;
16087   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16088   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16089   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16090   u32 action = ~0, w;
16091   ip4_address_t rmt_rloc4, lcl_rloc4;
16092   ip6_address_t rmt_rloc6, lcl_rloc6;
16093   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16094   int ret;
16095
16096   memset (&rloc, 0, sizeof (rloc));
16097
16098   /* Parse args required to build the message */
16099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16100     {
16101       if (unformat (input, "del"))
16102         is_add = 0;
16103       else if (unformat (input, "add"))
16104         is_add = 1;
16105       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16106         {
16107           rmt_eid_set = 1;
16108         }
16109       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16110         {
16111           lcl_eid_set = 1;
16112         }
16113       else if (unformat (input, "vrf %d", &dp_table))
16114         ;
16115       else if (unformat (input, "bd %d", &dp_table))
16116         ;
16117       else if (unformat (input, "vni %d", &vni))
16118         ;
16119       else if (unformat (input, "w %d", &w))
16120         {
16121           if (!curr_rloc)
16122             {
16123               errmsg ("No RLOC configured for setting priority/weight!");
16124               return -99;
16125             }
16126           curr_rloc->weight = w;
16127         }
16128       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16129                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16130         {
16131           rloc.is_ip4 = 1;
16132
16133           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16134           rloc.weight = 0;
16135           vec_add1 (lcl_locs, rloc);
16136
16137           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16138           vec_add1 (rmt_locs, rloc);
16139           /* weight saved in rmt loc */
16140           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16141         }
16142       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16143                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16144         {
16145           rloc.is_ip4 = 0;
16146           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16147           rloc.weight = 0;
16148           vec_add1 (lcl_locs, rloc);
16149
16150           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16151           vec_add1 (rmt_locs, rloc);
16152           /* weight saved in rmt loc */
16153           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16154         }
16155       else if (unformat (input, "action %d", &action))
16156         {
16157           ;
16158         }
16159       else
16160         {
16161           clib_warning ("parse error '%U'", format_unformat_error, input);
16162           return -99;
16163         }
16164     }
16165
16166   if (!rmt_eid_set)
16167     {
16168       errmsg ("remote eid addresses not set");
16169       return -99;
16170     }
16171
16172   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16173     {
16174       errmsg ("eid types don't match");
16175       return -99;
16176     }
16177
16178   if (0 == rmt_locs && (u32) ~ 0 == action)
16179     {
16180       errmsg ("action not set for negative mapping");
16181       return -99;
16182     }
16183
16184   /* Construct the API message */
16185   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16186       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16187
16188   mp->is_add = is_add;
16189   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16190   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16191   mp->eid_type = rmt_eid->type;
16192   mp->dp_table = clib_host_to_net_u32 (dp_table);
16193   mp->vni = clib_host_to_net_u32 (vni);
16194   mp->rmt_len = rmt_eid->len;
16195   mp->lcl_len = lcl_eid->len;
16196   mp->action = action;
16197
16198   if (0 != rmt_locs && 0 != lcl_locs)
16199     {
16200       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16201       clib_memcpy (mp->locs, lcl_locs,
16202                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16203
16204       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16205       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16206                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16207     }
16208   vec_free (lcl_locs);
16209   vec_free (rmt_locs);
16210
16211   /* send it... */
16212   S (mp);
16213
16214   /* Wait for a reply... */
16215   W (ret);
16216   return ret;
16217 }
16218
16219 static int
16220 api_one_add_del_map_server (vat_main_t * vam)
16221 {
16222   unformat_input_t *input = vam->input;
16223   vl_api_one_add_del_map_server_t *mp;
16224   u8 is_add = 1;
16225   u8 ipv4_set = 0;
16226   u8 ipv6_set = 0;
16227   ip4_address_t ipv4;
16228   ip6_address_t ipv6;
16229   int ret;
16230
16231   /* Parse args required to build the message */
16232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (input, "del"))
16235         {
16236           is_add = 0;
16237         }
16238       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16239         {
16240           ipv4_set = 1;
16241         }
16242       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16243         {
16244           ipv6_set = 1;
16245         }
16246       else
16247         break;
16248     }
16249
16250   if (ipv4_set && ipv6_set)
16251     {
16252       errmsg ("both eid v4 and v6 addresses set");
16253       return -99;
16254     }
16255
16256   if (!ipv4_set && !ipv6_set)
16257     {
16258       errmsg ("eid addresses not set");
16259       return -99;
16260     }
16261
16262   /* Construct the API message */
16263   M (ONE_ADD_DEL_MAP_SERVER, mp);
16264
16265   mp->is_add = is_add;
16266   if (ipv6_set)
16267     {
16268       mp->is_ipv6 = 1;
16269       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16270     }
16271   else
16272     {
16273       mp->is_ipv6 = 0;
16274       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16275     }
16276
16277   /* send it... */
16278   S (mp);
16279
16280   /* Wait for a reply... */
16281   W (ret);
16282   return ret;
16283 }
16284
16285 #define api_lisp_add_del_map_server api_one_add_del_map_server
16286
16287 static int
16288 api_one_add_del_map_resolver (vat_main_t * vam)
16289 {
16290   unformat_input_t *input = vam->input;
16291   vl_api_one_add_del_map_resolver_t *mp;
16292   u8 is_add = 1;
16293   u8 ipv4_set = 0;
16294   u8 ipv6_set = 0;
16295   ip4_address_t ipv4;
16296   ip6_address_t ipv6;
16297   int ret;
16298
16299   /* Parse args required to build the message */
16300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16301     {
16302       if (unformat (input, "del"))
16303         {
16304           is_add = 0;
16305         }
16306       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16307         {
16308           ipv4_set = 1;
16309         }
16310       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16311         {
16312           ipv6_set = 1;
16313         }
16314       else
16315         break;
16316     }
16317
16318   if (ipv4_set && ipv6_set)
16319     {
16320       errmsg ("both eid v4 and v6 addresses set");
16321       return -99;
16322     }
16323
16324   if (!ipv4_set && !ipv6_set)
16325     {
16326       errmsg ("eid addresses not set");
16327       return -99;
16328     }
16329
16330   /* Construct the API message */
16331   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16332
16333   mp->is_add = is_add;
16334   if (ipv6_set)
16335     {
16336       mp->is_ipv6 = 1;
16337       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16338     }
16339   else
16340     {
16341       mp->is_ipv6 = 0;
16342       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16343     }
16344
16345   /* send it... */
16346   S (mp);
16347
16348   /* Wait for a reply... */
16349   W (ret);
16350   return ret;
16351 }
16352
16353 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16354
16355 static int
16356 api_lisp_gpe_enable_disable (vat_main_t * vam)
16357 {
16358   unformat_input_t *input = vam->input;
16359   vl_api_gpe_enable_disable_t *mp;
16360   u8 is_set = 0;
16361   u8 is_en = 1;
16362   int ret;
16363
16364   /* Parse args required to build the message */
16365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16366     {
16367       if (unformat (input, "enable"))
16368         {
16369           is_set = 1;
16370           is_en = 1;
16371         }
16372       else if (unformat (input, "disable"))
16373         {
16374           is_set = 1;
16375           is_en = 0;
16376         }
16377       else
16378         break;
16379     }
16380
16381   if (is_set == 0)
16382     {
16383       errmsg ("Value not set");
16384       return -99;
16385     }
16386
16387   /* Construct the API message */
16388   M (GPE_ENABLE_DISABLE, mp);
16389
16390   mp->is_en = is_en;
16391
16392   /* send it... */
16393   S (mp);
16394
16395   /* Wait for a reply... */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 static int
16401 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16402 {
16403   unformat_input_t *input = vam->input;
16404   vl_api_one_rloc_probe_enable_disable_t *mp;
16405   u8 is_set = 0;
16406   u8 is_en = 0;
16407   int ret;
16408
16409   /* Parse args required to build the message */
16410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16411     {
16412       if (unformat (input, "enable"))
16413         {
16414           is_set = 1;
16415           is_en = 1;
16416         }
16417       else if (unformat (input, "disable"))
16418         is_set = 1;
16419       else
16420         break;
16421     }
16422
16423   if (!is_set)
16424     {
16425       errmsg ("Value not set");
16426       return -99;
16427     }
16428
16429   /* Construct the API message */
16430   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16431
16432   mp->is_enabled = is_en;
16433
16434   /* send it... */
16435   S (mp);
16436
16437   /* Wait for a reply... */
16438   W (ret);
16439   return ret;
16440 }
16441
16442 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16443
16444 static int
16445 api_one_map_register_enable_disable (vat_main_t * vam)
16446 {
16447   unformat_input_t *input = vam->input;
16448   vl_api_one_map_register_enable_disable_t *mp;
16449   u8 is_set = 0;
16450   u8 is_en = 0;
16451   int ret;
16452
16453   /* Parse args required to build the message */
16454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16455     {
16456       if (unformat (input, "enable"))
16457         {
16458           is_set = 1;
16459           is_en = 1;
16460         }
16461       else if (unformat (input, "disable"))
16462         is_set = 1;
16463       else
16464         break;
16465     }
16466
16467   if (!is_set)
16468     {
16469       errmsg ("Value not set");
16470       return -99;
16471     }
16472
16473   /* Construct the API message */
16474   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16475
16476   mp->is_enabled = is_en;
16477
16478   /* send it... */
16479   S (mp);
16480
16481   /* Wait for a reply... */
16482   W (ret);
16483   return ret;
16484 }
16485
16486 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16487
16488 static int
16489 api_one_enable_disable (vat_main_t * vam)
16490 {
16491   unformat_input_t *input = vam->input;
16492   vl_api_one_enable_disable_t *mp;
16493   u8 is_set = 0;
16494   u8 is_en = 0;
16495   int ret;
16496
16497   /* Parse args required to build the message */
16498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16499     {
16500       if (unformat (input, "enable"))
16501         {
16502           is_set = 1;
16503           is_en = 1;
16504         }
16505       else if (unformat (input, "disable"))
16506         {
16507           is_set = 1;
16508         }
16509       else
16510         break;
16511     }
16512
16513   if (!is_set)
16514     {
16515       errmsg ("Value not set");
16516       return -99;
16517     }
16518
16519   /* Construct the API message */
16520   M (ONE_ENABLE_DISABLE, mp);
16521
16522   mp->is_en = is_en;
16523
16524   /* send it... */
16525   S (mp);
16526
16527   /* Wait for a reply... */
16528   W (ret);
16529   return ret;
16530 }
16531
16532 #define api_lisp_enable_disable api_one_enable_disable
16533
16534 static int
16535 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16536 {
16537   unformat_input_t *input = vam->input;
16538   vl_api_one_enable_disable_xtr_mode_t *mp;
16539   u8 is_set = 0;
16540   u8 is_en = 0;
16541   int ret;
16542
16543   /* Parse args required to build the message */
16544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16545     {
16546       if (unformat (input, "enable"))
16547         {
16548           is_set = 1;
16549           is_en = 1;
16550         }
16551       else if (unformat (input, "disable"))
16552         {
16553           is_set = 1;
16554         }
16555       else
16556         break;
16557     }
16558
16559   if (!is_set)
16560     {
16561       errmsg ("Value not set");
16562       return -99;
16563     }
16564
16565   /* Construct the API message */
16566   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16567
16568   mp->is_en = is_en;
16569
16570   /* send it... */
16571   S (mp);
16572
16573   /* Wait for a reply... */
16574   W (ret);
16575   return ret;
16576 }
16577
16578 static int
16579 api_one_show_xtr_mode (vat_main_t * vam)
16580 {
16581   vl_api_one_show_xtr_mode_t *mp;
16582   int ret;
16583
16584   /* Construct the API message */
16585   M (ONE_SHOW_XTR_MODE, mp);
16586
16587   /* send it... */
16588   S (mp);
16589
16590   /* Wait for a reply... */
16591   W (ret);
16592   return ret;
16593 }
16594
16595 static int
16596 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16597 {
16598   unformat_input_t *input = vam->input;
16599   vl_api_one_enable_disable_pitr_mode_t *mp;
16600   u8 is_set = 0;
16601   u8 is_en = 0;
16602   int ret;
16603
16604   /* Parse args required to build the message */
16605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16606     {
16607       if (unformat (input, "enable"))
16608         {
16609           is_set = 1;
16610           is_en = 1;
16611         }
16612       else if (unformat (input, "disable"))
16613         {
16614           is_set = 1;
16615         }
16616       else
16617         break;
16618     }
16619
16620   if (!is_set)
16621     {
16622       errmsg ("Value not set");
16623       return -99;
16624     }
16625
16626   /* Construct the API message */
16627   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16628
16629   mp->is_en = is_en;
16630
16631   /* send it... */
16632   S (mp);
16633
16634   /* Wait for a reply... */
16635   W (ret);
16636   return ret;
16637 }
16638
16639 static int
16640 api_one_show_pitr_mode (vat_main_t * vam)
16641 {
16642   vl_api_one_show_pitr_mode_t *mp;
16643   int ret;
16644
16645   /* Construct the API message */
16646   M (ONE_SHOW_PITR_MODE, mp);
16647
16648   /* send it... */
16649   S (mp);
16650
16651   /* Wait for a reply... */
16652   W (ret);
16653   return ret;
16654 }
16655
16656 static int
16657 api_one_enable_disable_petr_mode (vat_main_t * vam)
16658 {
16659   unformat_input_t *input = vam->input;
16660   vl_api_one_enable_disable_petr_mode_t *mp;
16661   u8 is_set = 0;
16662   u8 is_en = 0;
16663   int ret;
16664
16665   /* Parse args required to build the message */
16666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16667     {
16668       if (unformat (input, "enable"))
16669         {
16670           is_set = 1;
16671           is_en = 1;
16672         }
16673       else if (unformat (input, "disable"))
16674         {
16675           is_set = 1;
16676         }
16677       else
16678         break;
16679     }
16680
16681   if (!is_set)
16682     {
16683       errmsg ("Value not set");
16684       return -99;
16685     }
16686
16687   /* Construct the API message */
16688   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16689
16690   mp->is_en = is_en;
16691
16692   /* send it... */
16693   S (mp);
16694
16695   /* Wait for a reply... */
16696   W (ret);
16697   return ret;
16698 }
16699
16700 static int
16701 api_one_show_petr_mode (vat_main_t * vam)
16702 {
16703   vl_api_one_show_petr_mode_t *mp;
16704   int ret;
16705
16706   /* Construct the API message */
16707   M (ONE_SHOW_PETR_MODE, mp);
16708
16709   /* send it... */
16710   S (mp);
16711
16712   /* Wait for a reply... */
16713   W (ret);
16714   return ret;
16715 }
16716
16717 static int
16718 api_show_one_map_register_state (vat_main_t * vam)
16719 {
16720   vl_api_show_one_map_register_state_t *mp;
16721   int ret;
16722
16723   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16724
16725   /* send */
16726   S (mp);
16727
16728   /* wait for reply */
16729   W (ret);
16730   return ret;
16731 }
16732
16733 #define api_show_lisp_map_register_state api_show_one_map_register_state
16734
16735 static int
16736 api_show_one_rloc_probe_state (vat_main_t * vam)
16737 {
16738   vl_api_show_one_rloc_probe_state_t *mp;
16739   int ret;
16740
16741   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16742
16743   /* send */
16744   S (mp);
16745
16746   /* wait for reply */
16747   W (ret);
16748   return ret;
16749 }
16750
16751 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16752
16753 static int
16754 api_one_add_del_ndp_entry (vat_main_t * vam)
16755 {
16756   vl_api_one_add_del_ndp_entry_t *mp;
16757   unformat_input_t *input = vam->input;
16758   u8 is_add = 1;
16759   u8 mac_set = 0;
16760   u8 bd_set = 0;
16761   u8 ip_set = 0;
16762   u8 mac[6] = { 0, };
16763   u8 ip6[16] = { 0, };
16764   u32 bd = ~0;
16765   int ret;
16766
16767   /* Parse args required to build the message */
16768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16769     {
16770       if (unformat (input, "del"))
16771         is_add = 0;
16772       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16773         mac_set = 1;
16774       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16775         ip_set = 1;
16776       else if (unformat (input, "bd %d", &bd))
16777         bd_set = 1;
16778       else
16779         {
16780           errmsg ("parse error '%U'", format_unformat_error, input);
16781           return -99;
16782         }
16783     }
16784
16785   if (!bd_set || !ip_set || (!mac_set && is_add))
16786     {
16787       errmsg ("Missing BD, IP or MAC!");
16788       return -99;
16789     }
16790
16791   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16792   mp->is_add = is_add;
16793   clib_memcpy (mp->mac, mac, 6);
16794   mp->bd = clib_host_to_net_u32 (bd);
16795   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16796
16797   /* send */
16798   S (mp);
16799
16800   /* wait for reply */
16801   W (ret);
16802   return ret;
16803 }
16804
16805 static int
16806 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16807 {
16808   vl_api_one_add_del_l2_arp_entry_t *mp;
16809   unformat_input_t *input = vam->input;
16810   u8 is_add = 1;
16811   u8 mac_set = 0;
16812   u8 bd_set = 0;
16813   u8 ip_set = 0;
16814   u8 mac[6] = { 0, };
16815   u32 ip4 = 0, bd = ~0;
16816   int ret;
16817
16818   /* Parse args required to build the message */
16819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16820     {
16821       if (unformat (input, "del"))
16822         is_add = 0;
16823       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16824         mac_set = 1;
16825       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16826         ip_set = 1;
16827       else if (unformat (input, "bd %d", &bd))
16828         bd_set = 1;
16829       else
16830         {
16831           errmsg ("parse error '%U'", format_unformat_error, input);
16832           return -99;
16833         }
16834     }
16835
16836   if (!bd_set || !ip_set || (!mac_set && is_add))
16837     {
16838       errmsg ("Missing BD, IP or MAC!");
16839       return -99;
16840     }
16841
16842   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16843   mp->is_add = is_add;
16844   clib_memcpy (mp->mac, mac, 6);
16845   mp->bd = clib_host_to_net_u32 (bd);
16846   mp->ip4 = ip4;
16847
16848   /* send */
16849   S (mp);
16850
16851   /* wait for reply */
16852   W (ret);
16853   return ret;
16854 }
16855
16856 static int
16857 api_one_ndp_bd_get (vat_main_t * vam)
16858 {
16859   vl_api_one_ndp_bd_get_t *mp;
16860   int ret;
16861
16862   M (ONE_NDP_BD_GET, mp);
16863
16864   /* send */
16865   S (mp);
16866
16867   /* wait for reply */
16868   W (ret);
16869   return ret;
16870 }
16871
16872 static int
16873 api_one_ndp_entries_get (vat_main_t * vam)
16874 {
16875   vl_api_one_ndp_entries_get_t *mp;
16876   unformat_input_t *input = vam->input;
16877   u8 bd_set = 0;
16878   u32 bd = ~0;
16879   int ret;
16880
16881   /* Parse args required to build the message */
16882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16883     {
16884       if (unformat (input, "bd %d", &bd))
16885         bd_set = 1;
16886       else
16887         {
16888           errmsg ("parse error '%U'", format_unformat_error, input);
16889           return -99;
16890         }
16891     }
16892
16893   if (!bd_set)
16894     {
16895       errmsg ("Expected bridge domain!");
16896       return -99;
16897     }
16898
16899   M (ONE_NDP_ENTRIES_GET, mp);
16900   mp->bd = clib_host_to_net_u32 (bd);
16901
16902   /* send */
16903   S (mp);
16904
16905   /* wait for reply */
16906   W (ret);
16907   return ret;
16908 }
16909
16910 static int
16911 api_one_l2_arp_bd_get (vat_main_t * vam)
16912 {
16913   vl_api_one_l2_arp_bd_get_t *mp;
16914   int ret;
16915
16916   M (ONE_L2_ARP_BD_GET, mp);
16917
16918   /* send */
16919   S (mp);
16920
16921   /* wait for reply */
16922   W (ret);
16923   return ret;
16924 }
16925
16926 static int
16927 api_one_l2_arp_entries_get (vat_main_t * vam)
16928 {
16929   vl_api_one_l2_arp_entries_get_t *mp;
16930   unformat_input_t *input = vam->input;
16931   u8 bd_set = 0;
16932   u32 bd = ~0;
16933   int ret;
16934
16935   /* Parse args required to build the message */
16936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16937     {
16938       if (unformat (input, "bd %d", &bd))
16939         bd_set = 1;
16940       else
16941         {
16942           errmsg ("parse error '%U'", format_unformat_error, input);
16943           return -99;
16944         }
16945     }
16946
16947   if (!bd_set)
16948     {
16949       errmsg ("Expected bridge domain!");
16950       return -99;
16951     }
16952
16953   M (ONE_L2_ARP_ENTRIES_GET, mp);
16954   mp->bd = clib_host_to_net_u32 (bd);
16955
16956   /* send */
16957   S (mp);
16958
16959   /* wait for reply */
16960   W (ret);
16961   return ret;
16962 }
16963
16964 static int
16965 api_one_stats_enable_disable (vat_main_t * vam)
16966 {
16967   vl_api_one_stats_enable_disable_t *mp;
16968   unformat_input_t *input = vam->input;
16969   u8 is_set = 0;
16970   u8 is_en = 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, "enable"))
16977         {
16978           is_set = 1;
16979           is_en = 1;
16980         }
16981       else if (unformat (input, "disable"))
16982         {
16983           is_set = 1;
16984         }
16985       else
16986         break;
16987     }
16988
16989   if (!is_set)
16990     {
16991       errmsg ("Value not set");
16992       return -99;
16993     }
16994
16995   M (ONE_STATS_ENABLE_DISABLE, mp);
16996   mp->is_en = is_en;
16997
16998   /* send */
16999   S (mp);
17000
17001   /* wait for reply */
17002   W (ret);
17003   return ret;
17004 }
17005
17006 static int
17007 api_show_one_stats_enable_disable (vat_main_t * vam)
17008 {
17009   vl_api_show_one_stats_enable_disable_t *mp;
17010   int ret;
17011
17012   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17013
17014   /* send */
17015   S (mp);
17016
17017   /* wait for reply */
17018   W (ret);
17019   return ret;
17020 }
17021
17022 static int
17023 api_show_one_map_request_mode (vat_main_t * vam)
17024 {
17025   vl_api_show_one_map_request_mode_t *mp;
17026   int ret;
17027
17028   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17029
17030   /* send */
17031   S (mp);
17032
17033   /* wait for reply */
17034   W (ret);
17035   return ret;
17036 }
17037
17038 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17039
17040 static int
17041 api_one_map_request_mode (vat_main_t * vam)
17042 {
17043   unformat_input_t *input = vam->input;
17044   vl_api_one_map_request_mode_t *mp;
17045   u8 mode = 0;
17046   int ret;
17047
17048   /* Parse args required to build the message */
17049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17050     {
17051       if (unformat (input, "dst-only"))
17052         mode = 0;
17053       else if (unformat (input, "src-dst"))
17054         mode = 1;
17055       else
17056         {
17057           errmsg ("parse error '%U'", format_unformat_error, input);
17058           return -99;
17059         }
17060     }
17061
17062   M (ONE_MAP_REQUEST_MODE, mp);
17063
17064   mp->mode = mode;
17065
17066   /* send */
17067   S (mp);
17068
17069   /* wait for reply */
17070   W (ret);
17071   return ret;
17072 }
17073
17074 #define api_lisp_map_request_mode api_one_map_request_mode
17075
17076 /**
17077  * Enable/disable ONE proxy ITR.
17078  *
17079  * @param vam vpp API test context
17080  * @return return code
17081  */
17082 static int
17083 api_one_pitr_set_locator_set (vat_main_t * vam)
17084 {
17085   u8 ls_name_set = 0;
17086   unformat_input_t *input = vam->input;
17087   vl_api_one_pitr_set_locator_set_t *mp;
17088   u8 is_add = 1;
17089   u8 *ls_name = 0;
17090   int ret;
17091
17092   /* Parse args required to build the message */
17093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17094     {
17095       if (unformat (input, "del"))
17096         is_add = 0;
17097       else if (unformat (input, "locator-set %s", &ls_name))
17098         ls_name_set = 1;
17099       else
17100         {
17101           errmsg ("parse error '%U'", format_unformat_error, input);
17102           return -99;
17103         }
17104     }
17105
17106   if (!ls_name_set)
17107     {
17108       errmsg ("locator-set name not set!");
17109       return -99;
17110     }
17111
17112   M (ONE_PITR_SET_LOCATOR_SET, mp);
17113
17114   mp->is_add = is_add;
17115   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17116   vec_free (ls_name);
17117
17118   /* send */
17119   S (mp);
17120
17121   /* wait for reply */
17122   W (ret);
17123   return ret;
17124 }
17125
17126 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17127
17128 static int
17129 api_one_nsh_set_locator_set (vat_main_t * vam)
17130 {
17131   u8 ls_name_set = 0;
17132   unformat_input_t *input = vam->input;
17133   vl_api_one_nsh_set_locator_set_t *mp;
17134   u8 is_add = 1;
17135   u8 *ls_name = 0;
17136   int ret;
17137
17138   /* Parse args required to build the message */
17139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17140     {
17141       if (unformat (input, "del"))
17142         is_add = 0;
17143       else if (unformat (input, "ls %s", &ls_name))
17144         ls_name_set = 1;
17145       else
17146         {
17147           errmsg ("parse error '%U'", format_unformat_error, input);
17148           return -99;
17149         }
17150     }
17151
17152   if (!ls_name_set && is_add)
17153     {
17154       errmsg ("locator-set name not set!");
17155       return -99;
17156     }
17157
17158   M (ONE_NSH_SET_LOCATOR_SET, mp);
17159
17160   mp->is_add = is_add;
17161   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17162   vec_free (ls_name);
17163
17164   /* send */
17165   S (mp);
17166
17167   /* wait for reply */
17168   W (ret);
17169   return ret;
17170 }
17171
17172 static int
17173 api_show_one_pitr (vat_main_t * vam)
17174 {
17175   vl_api_show_one_pitr_t *mp;
17176   int ret;
17177
17178   if (!vam->json_output)
17179     {
17180       print (vam->ofp, "%=20s", "lisp status:");
17181     }
17182
17183   M (SHOW_ONE_PITR, mp);
17184   /* send it... */
17185   S (mp);
17186
17187   /* Wait for a reply... */
17188   W (ret);
17189   return ret;
17190 }
17191
17192 #define api_show_lisp_pitr api_show_one_pitr
17193
17194 static int
17195 api_one_use_petr (vat_main_t * vam)
17196 {
17197   unformat_input_t *input = vam->input;
17198   vl_api_one_use_petr_t *mp;
17199   u8 is_add = 0;
17200   ip_address_t ip;
17201   int ret;
17202
17203   memset (&ip, 0, sizeof (ip));
17204
17205   /* Parse args required to build the message */
17206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17207     {
17208       if (unformat (input, "disable"))
17209         is_add = 0;
17210       else
17211         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17212         {
17213           is_add = 1;
17214           ip_addr_version (&ip) = IP4;
17215         }
17216       else
17217         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17218         {
17219           is_add = 1;
17220           ip_addr_version (&ip) = IP6;
17221         }
17222       else
17223         {
17224           errmsg ("parse error '%U'", format_unformat_error, input);
17225           return -99;
17226         }
17227     }
17228
17229   M (ONE_USE_PETR, mp);
17230
17231   mp->is_add = is_add;
17232   if (is_add)
17233     {
17234       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17235       if (mp->is_ip4)
17236         clib_memcpy (mp->address, &ip, 4);
17237       else
17238         clib_memcpy (mp->address, &ip, 16);
17239     }
17240
17241   /* send */
17242   S (mp);
17243
17244   /* wait for reply */
17245   W (ret);
17246   return ret;
17247 }
17248
17249 #define api_lisp_use_petr api_one_use_petr
17250
17251 static int
17252 api_show_one_nsh_mapping (vat_main_t * vam)
17253 {
17254   vl_api_show_one_use_petr_t *mp;
17255   int ret;
17256
17257   if (!vam->json_output)
17258     {
17259       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17260     }
17261
17262   M (SHOW_ONE_NSH_MAPPING, mp);
17263   /* send it... */
17264   S (mp);
17265
17266   /* Wait for a reply... */
17267   W (ret);
17268   return ret;
17269 }
17270
17271 static int
17272 api_show_one_use_petr (vat_main_t * vam)
17273 {
17274   vl_api_show_one_use_petr_t *mp;
17275   int ret;
17276
17277   if (!vam->json_output)
17278     {
17279       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17280     }
17281
17282   M (SHOW_ONE_USE_PETR, mp);
17283   /* send it... */
17284   S (mp);
17285
17286   /* Wait for a reply... */
17287   W (ret);
17288   return ret;
17289 }
17290
17291 #define api_show_lisp_use_petr api_show_one_use_petr
17292
17293 /**
17294  * Add/delete mapping between vni and vrf
17295  */
17296 static int
17297 api_one_eid_table_add_del_map (vat_main_t * vam)
17298 {
17299   unformat_input_t *input = vam->input;
17300   vl_api_one_eid_table_add_del_map_t *mp;
17301   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17302   u32 vni, vrf, bd_index;
17303   int ret;
17304
17305   /* Parse args required to build the message */
17306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17307     {
17308       if (unformat (input, "del"))
17309         is_add = 0;
17310       else if (unformat (input, "vrf %d", &vrf))
17311         vrf_set = 1;
17312       else if (unformat (input, "bd_index %d", &bd_index))
17313         bd_index_set = 1;
17314       else if (unformat (input, "vni %d", &vni))
17315         vni_set = 1;
17316       else
17317         break;
17318     }
17319
17320   if (!vni_set || (!vrf_set && !bd_index_set))
17321     {
17322       errmsg ("missing arguments!");
17323       return -99;
17324     }
17325
17326   if (vrf_set && bd_index_set)
17327     {
17328       errmsg ("error: both vrf and bd entered!");
17329       return -99;
17330     }
17331
17332   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17333
17334   mp->is_add = is_add;
17335   mp->vni = htonl (vni);
17336   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17337   mp->is_l2 = bd_index_set;
17338
17339   /* send */
17340   S (mp);
17341
17342   /* wait for reply */
17343   W (ret);
17344   return ret;
17345 }
17346
17347 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17348
17349 uword
17350 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17351 {
17352   u32 *action = va_arg (*args, u32 *);
17353   u8 *s = 0;
17354
17355   if (unformat (input, "%s", &s))
17356     {
17357       if (!strcmp ((char *) s, "no-action"))
17358         action[0] = 0;
17359       else if (!strcmp ((char *) s, "natively-forward"))
17360         action[0] = 1;
17361       else if (!strcmp ((char *) s, "send-map-request"))
17362         action[0] = 2;
17363       else if (!strcmp ((char *) s, "drop"))
17364         action[0] = 3;
17365       else
17366         {
17367           clib_warning ("invalid action: '%s'", s);
17368           action[0] = 3;
17369         }
17370     }
17371   else
17372     return 0;
17373
17374   vec_free (s);
17375   return 1;
17376 }
17377
17378 /**
17379  * Add/del remote mapping to/from ONE control plane
17380  *
17381  * @param vam vpp API test context
17382  * @return return code
17383  */
17384 static int
17385 api_one_add_del_remote_mapping (vat_main_t * vam)
17386 {
17387   unformat_input_t *input = vam->input;
17388   vl_api_one_add_del_remote_mapping_t *mp;
17389   u32 vni = 0;
17390   lisp_eid_vat_t _eid, *eid = &_eid;
17391   lisp_eid_vat_t _seid, *seid = &_seid;
17392   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17393   u32 action = ~0, p, w, data_len;
17394   ip4_address_t rloc4;
17395   ip6_address_t rloc6;
17396   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17397   int ret;
17398
17399   memset (&rloc, 0, sizeof (rloc));
17400
17401   /* Parse args required to build the message */
17402   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17403     {
17404       if (unformat (input, "del-all"))
17405         {
17406           del_all = 1;
17407         }
17408       else if (unformat (input, "del"))
17409         {
17410           is_add = 0;
17411         }
17412       else if (unformat (input, "add"))
17413         {
17414           is_add = 1;
17415         }
17416       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17417         {
17418           eid_set = 1;
17419         }
17420       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17421         {
17422           seid_set = 1;
17423         }
17424       else if (unformat (input, "vni %d", &vni))
17425         {
17426           ;
17427         }
17428       else if (unformat (input, "p %d w %d", &p, &w))
17429         {
17430           if (!curr_rloc)
17431             {
17432               errmsg ("No RLOC configured for setting priority/weight!");
17433               return -99;
17434             }
17435           curr_rloc->priority = p;
17436           curr_rloc->weight = w;
17437         }
17438       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17439         {
17440           rloc.is_ip4 = 1;
17441           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17442           vec_add1 (rlocs, rloc);
17443           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17444         }
17445       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17446         {
17447           rloc.is_ip4 = 0;
17448           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17449           vec_add1 (rlocs, rloc);
17450           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17451         }
17452       else if (unformat (input, "action %U",
17453                          unformat_negative_mapping_action, &action))
17454         {
17455           ;
17456         }
17457       else
17458         {
17459           clib_warning ("parse error '%U'", format_unformat_error, input);
17460           return -99;
17461         }
17462     }
17463
17464   if (0 == eid_set)
17465     {
17466       errmsg ("missing params!");
17467       return -99;
17468     }
17469
17470   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17471     {
17472       errmsg ("no action set for negative map-reply!");
17473       return -99;
17474     }
17475
17476   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17477
17478   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17479   mp->is_add = is_add;
17480   mp->vni = htonl (vni);
17481   mp->action = (u8) action;
17482   mp->is_src_dst = seid_set;
17483   mp->eid_len = eid->len;
17484   mp->seid_len = seid->len;
17485   mp->del_all = del_all;
17486   mp->eid_type = eid->type;
17487   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17488   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17489
17490   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17491   clib_memcpy (mp->rlocs, rlocs, data_len);
17492   vec_free (rlocs);
17493
17494   /* send it... */
17495   S (mp);
17496
17497   /* Wait for a reply... */
17498   W (ret);
17499   return ret;
17500 }
17501
17502 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17503
17504 /**
17505  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17506  * forwarding entries in data-plane accordingly.
17507  *
17508  * @param vam vpp API test context
17509  * @return return code
17510  */
17511 static int
17512 api_one_add_del_adjacency (vat_main_t * vam)
17513 {
17514   unformat_input_t *input = vam->input;
17515   vl_api_one_add_del_adjacency_t *mp;
17516   u32 vni = 0;
17517   ip4_address_t leid4, reid4;
17518   ip6_address_t leid6, reid6;
17519   u8 reid_mac[6] = { 0 };
17520   u8 leid_mac[6] = { 0 };
17521   u8 reid_type, leid_type;
17522   u32 leid_len = 0, reid_len = 0, len;
17523   u8 is_add = 1;
17524   int ret;
17525
17526   leid_type = reid_type = (u8) ~ 0;
17527
17528   /* Parse args required to build the message */
17529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17530     {
17531       if (unformat (input, "del"))
17532         {
17533           is_add = 0;
17534         }
17535       else if (unformat (input, "add"))
17536         {
17537           is_add = 1;
17538         }
17539       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17540                          &reid4, &len))
17541         {
17542           reid_type = 0;        /* ipv4 */
17543           reid_len = len;
17544         }
17545       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17546                          &reid6, &len))
17547         {
17548           reid_type = 1;        /* ipv6 */
17549           reid_len = len;
17550         }
17551       else if (unformat (input, "reid %U", unformat_ethernet_address,
17552                          reid_mac))
17553         {
17554           reid_type = 2;        /* mac */
17555         }
17556       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17557                          &leid4, &len))
17558         {
17559           leid_type = 0;        /* ipv4 */
17560           leid_len = len;
17561         }
17562       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17563                          &leid6, &len))
17564         {
17565           leid_type = 1;        /* ipv6 */
17566           leid_len = len;
17567         }
17568       else if (unformat (input, "leid %U", unformat_ethernet_address,
17569                          leid_mac))
17570         {
17571           leid_type = 2;        /* mac */
17572         }
17573       else if (unformat (input, "vni %d", &vni))
17574         {
17575           ;
17576         }
17577       else
17578         {
17579           errmsg ("parse error '%U'", format_unformat_error, input);
17580           return -99;
17581         }
17582     }
17583
17584   if ((u8) ~ 0 == reid_type)
17585     {
17586       errmsg ("missing params!");
17587       return -99;
17588     }
17589
17590   if (leid_type != reid_type)
17591     {
17592       errmsg ("remote and local EIDs are of different types!");
17593       return -99;
17594     }
17595
17596   M (ONE_ADD_DEL_ADJACENCY, mp);
17597   mp->is_add = is_add;
17598   mp->vni = htonl (vni);
17599   mp->leid_len = leid_len;
17600   mp->reid_len = reid_len;
17601   mp->eid_type = reid_type;
17602
17603   switch (mp->eid_type)
17604     {
17605     case 0:
17606       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17607       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17608       break;
17609     case 1:
17610       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17611       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17612       break;
17613     case 2:
17614       clib_memcpy (mp->leid, leid_mac, 6);
17615       clib_memcpy (mp->reid, reid_mac, 6);
17616       break;
17617     default:
17618       errmsg ("unknown EID type %d!", mp->eid_type);
17619       return 0;
17620     }
17621
17622   /* send it... */
17623   S (mp);
17624
17625   /* Wait for a reply... */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17631
17632 uword
17633 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17634 {
17635   u32 *mode = va_arg (*args, u32 *);
17636
17637   if (unformat (input, "lisp"))
17638     *mode = 0;
17639   else if (unformat (input, "vxlan"))
17640     *mode = 1;
17641   else
17642     return 0;
17643
17644   return 1;
17645 }
17646
17647 static int
17648 api_gpe_get_encap_mode (vat_main_t * vam)
17649 {
17650   vl_api_gpe_get_encap_mode_t *mp;
17651   int ret;
17652
17653   /* Construct the API message */
17654   M (GPE_GET_ENCAP_MODE, mp);
17655
17656   /* send it... */
17657   S (mp);
17658
17659   /* Wait for a reply... */
17660   W (ret);
17661   return ret;
17662 }
17663
17664 static int
17665 api_gpe_set_encap_mode (vat_main_t * vam)
17666 {
17667   unformat_input_t *input = vam->input;
17668   vl_api_gpe_set_encap_mode_t *mp;
17669   int ret;
17670   u32 mode = 0;
17671
17672   /* Parse args required to build the message */
17673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17674     {
17675       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17676         ;
17677       else
17678         break;
17679     }
17680
17681   /* Construct the API message */
17682   M (GPE_SET_ENCAP_MODE, mp);
17683
17684   mp->mode = mode;
17685
17686   /* send it... */
17687   S (mp);
17688
17689   /* Wait for a reply... */
17690   W (ret);
17691   return ret;
17692 }
17693
17694 static int
17695 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17696 {
17697   unformat_input_t *input = vam->input;
17698   vl_api_gpe_add_del_iface_t *mp;
17699   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17700   u32 dp_table = 0, vni = 0;
17701   int ret;
17702
17703   /* Parse args required to build the message */
17704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17705     {
17706       if (unformat (input, "up"))
17707         {
17708           action_set = 1;
17709           is_add = 1;
17710         }
17711       else if (unformat (input, "down"))
17712         {
17713           action_set = 1;
17714           is_add = 0;
17715         }
17716       else if (unformat (input, "table_id %d", &dp_table))
17717         {
17718           dp_table_set = 1;
17719         }
17720       else if (unformat (input, "bd_id %d", &dp_table))
17721         {
17722           dp_table_set = 1;
17723           is_l2 = 1;
17724         }
17725       else if (unformat (input, "vni %d", &vni))
17726         {
17727           vni_set = 1;
17728         }
17729       else
17730         break;
17731     }
17732
17733   if (action_set == 0)
17734     {
17735       errmsg ("Action not set");
17736       return -99;
17737     }
17738   if (dp_table_set == 0 || vni_set == 0)
17739     {
17740       errmsg ("vni and dp_table must be set");
17741       return -99;
17742     }
17743
17744   /* Construct the API message */
17745   M (GPE_ADD_DEL_IFACE, mp);
17746
17747   mp->is_add = is_add;
17748   mp->dp_table = clib_host_to_net_u32 (dp_table);
17749   mp->is_l2 = is_l2;
17750   mp->vni = clib_host_to_net_u32 (vni);
17751
17752   /* send it... */
17753   S (mp);
17754
17755   /* Wait for a reply... */
17756   W (ret);
17757   return ret;
17758 }
17759
17760 static int
17761 api_one_map_register_fallback_threshold (vat_main_t * vam)
17762 {
17763   unformat_input_t *input = vam->input;
17764   vl_api_one_map_register_fallback_threshold_t *mp;
17765   u32 value = 0;
17766   u8 is_set = 0;
17767   int ret;
17768
17769   /* Parse args required to build the message */
17770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17771     {
17772       if (unformat (input, "%u", &value))
17773         is_set = 1;
17774       else
17775         {
17776           clib_warning ("parse error '%U'", format_unformat_error, input);
17777           return -99;
17778         }
17779     }
17780
17781   if (!is_set)
17782     {
17783       errmsg ("fallback threshold value is missing!");
17784       return -99;
17785     }
17786
17787   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17788   mp->value = clib_host_to_net_u32 (value);
17789
17790   /* send it... */
17791   S (mp);
17792
17793   /* Wait for a reply... */
17794   W (ret);
17795   return ret;
17796 }
17797
17798 static int
17799 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17800 {
17801   vl_api_show_one_map_register_fallback_threshold_t *mp;
17802   int ret;
17803
17804   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17805
17806   /* send it... */
17807   S (mp);
17808
17809   /* Wait for a reply... */
17810   W (ret);
17811   return ret;
17812 }
17813
17814 uword
17815 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17816 {
17817   u32 *proto = va_arg (*args, u32 *);
17818
17819   if (unformat (input, "udp"))
17820     *proto = 1;
17821   else if (unformat (input, "api"))
17822     *proto = 2;
17823   else
17824     return 0;
17825
17826   return 1;
17827 }
17828
17829 static int
17830 api_one_set_transport_protocol (vat_main_t * vam)
17831 {
17832   unformat_input_t *input = vam->input;
17833   vl_api_one_set_transport_protocol_t *mp;
17834   u8 is_set = 0;
17835   u32 protocol = 0;
17836   int ret;
17837
17838   /* Parse args required to build the message */
17839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17840     {
17841       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17842         is_set = 1;
17843       else
17844         {
17845           clib_warning ("parse error '%U'", format_unformat_error, input);
17846           return -99;
17847         }
17848     }
17849
17850   if (!is_set)
17851     {
17852       errmsg ("Transport protocol missing!");
17853       return -99;
17854     }
17855
17856   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17857   mp->protocol = (u8) protocol;
17858
17859   /* send it... */
17860   S (mp);
17861
17862   /* Wait for a reply... */
17863   W (ret);
17864   return ret;
17865 }
17866
17867 static int
17868 api_one_get_transport_protocol (vat_main_t * vam)
17869 {
17870   vl_api_one_get_transport_protocol_t *mp;
17871   int ret;
17872
17873   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17874
17875   /* send it... */
17876   S (mp);
17877
17878   /* Wait for a reply... */
17879   W (ret);
17880   return ret;
17881 }
17882
17883 static int
17884 api_one_map_register_set_ttl (vat_main_t * vam)
17885 {
17886   unformat_input_t *input = vam->input;
17887   vl_api_one_map_register_set_ttl_t *mp;
17888   u32 ttl = 0;
17889   u8 is_set = 0;
17890   int ret;
17891
17892   /* Parse args required to build the message */
17893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17894     {
17895       if (unformat (input, "%u", &ttl))
17896         is_set = 1;
17897       else
17898         {
17899           clib_warning ("parse error '%U'", format_unformat_error, input);
17900           return -99;
17901         }
17902     }
17903
17904   if (!is_set)
17905     {
17906       errmsg ("TTL value missing!");
17907       return -99;
17908     }
17909
17910   M (ONE_MAP_REGISTER_SET_TTL, mp);
17911   mp->ttl = clib_host_to_net_u32 (ttl);
17912
17913   /* send it... */
17914   S (mp);
17915
17916   /* Wait for a reply... */
17917   W (ret);
17918   return ret;
17919 }
17920
17921 static int
17922 api_show_one_map_register_ttl (vat_main_t * vam)
17923 {
17924   vl_api_show_one_map_register_ttl_t *mp;
17925   int ret;
17926
17927   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17928
17929   /* send it... */
17930   S (mp);
17931
17932   /* Wait for a reply... */
17933   W (ret);
17934   return ret;
17935 }
17936
17937 /**
17938  * Add/del map request itr rlocs from ONE control plane and updates
17939  *
17940  * @param vam vpp API test context
17941  * @return return code
17942  */
17943 static int
17944 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17945 {
17946   unformat_input_t *input = vam->input;
17947   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17948   u8 *locator_set_name = 0;
17949   u8 locator_set_name_set = 0;
17950   u8 is_add = 1;
17951   int ret;
17952
17953   /* Parse args required to build the message */
17954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17955     {
17956       if (unformat (input, "del"))
17957         {
17958           is_add = 0;
17959         }
17960       else if (unformat (input, "%_%v%_", &locator_set_name))
17961         {
17962           locator_set_name_set = 1;
17963         }
17964       else
17965         {
17966           clib_warning ("parse error '%U'", format_unformat_error, input);
17967           return -99;
17968         }
17969     }
17970
17971   if (is_add && !locator_set_name_set)
17972     {
17973       errmsg ("itr-rloc is not set!");
17974       return -99;
17975     }
17976
17977   if (is_add && vec_len (locator_set_name) > 64)
17978     {
17979       errmsg ("itr-rloc locator-set name too long");
17980       vec_free (locator_set_name);
17981       return -99;
17982     }
17983
17984   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17985   mp->is_add = is_add;
17986   if (is_add)
17987     {
17988       clib_memcpy (mp->locator_set_name, locator_set_name,
17989                    vec_len (locator_set_name));
17990     }
17991   else
17992     {
17993       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17994     }
17995   vec_free (locator_set_name);
17996
17997   /* send it... */
17998   S (mp);
17999
18000   /* Wait for a reply... */
18001   W (ret);
18002   return ret;
18003 }
18004
18005 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18006
18007 static int
18008 api_one_locator_dump (vat_main_t * vam)
18009 {
18010   unformat_input_t *input = vam->input;
18011   vl_api_one_locator_dump_t *mp;
18012   vl_api_control_ping_t *mp_ping;
18013   u8 is_index_set = 0, is_name_set = 0;
18014   u8 *ls_name = 0;
18015   u32 ls_index = ~0;
18016   int ret;
18017
18018   /* Parse args required to build the message */
18019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18020     {
18021       if (unformat (input, "ls_name %_%v%_", &ls_name))
18022         {
18023           is_name_set = 1;
18024         }
18025       else if (unformat (input, "ls_index %d", &ls_index))
18026         {
18027           is_index_set = 1;
18028         }
18029       else
18030         {
18031           errmsg ("parse error '%U'", format_unformat_error, input);
18032           return -99;
18033         }
18034     }
18035
18036   if (!is_index_set && !is_name_set)
18037     {
18038       errmsg ("error: expected one of index or name!");
18039       return -99;
18040     }
18041
18042   if (is_index_set && is_name_set)
18043     {
18044       errmsg ("error: only one param expected!");
18045       return -99;
18046     }
18047
18048   if (vec_len (ls_name) > 62)
18049     {
18050       errmsg ("error: locator set name too long!");
18051       return -99;
18052     }
18053
18054   if (!vam->json_output)
18055     {
18056       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18057     }
18058
18059   M (ONE_LOCATOR_DUMP, mp);
18060   mp->is_index_set = is_index_set;
18061
18062   if (is_index_set)
18063     mp->ls_index = clib_host_to_net_u32 (ls_index);
18064   else
18065     {
18066       vec_add1 (ls_name, 0);
18067       strncpy ((char *) mp->ls_name, (char *) ls_name,
18068                sizeof (mp->ls_name) - 1);
18069     }
18070
18071   /* send it... */
18072   S (mp);
18073
18074   /* Use a control ping for synchronization */
18075   MPING (CONTROL_PING, mp_ping);
18076   S (mp_ping);
18077
18078   /* Wait for a reply... */
18079   W (ret);
18080   return ret;
18081 }
18082
18083 #define api_lisp_locator_dump api_one_locator_dump
18084
18085 static int
18086 api_one_locator_set_dump (vat_main_t * vam)
18087 {
18088   vl_api_one_locator_set_dump_t *mp;
18089   vl_api_control_ping_t *mp_ping;
18090   unformat_input_t *input = vam->input;
18091   u8 filter = 0;
18092   int ret;
18093
18094   /* Parse args required to build the message */
18095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18096     {
18097       if (unformat (input, "local"))
18098         {
18099           filter = 1;
18100         }
18101       else if (unformat (input, "remote"))
18102         {
18103           filter = 2;
18104         }
18105       else
18106         {
18107           errmsg ("parse error '%U'", format_unformat_error, input);
18108           return -99;
18109         }
18110     }
18111
18112   if (!vam->json_output)
18113     {
18114       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18115     }
18116
18117   M (ONE_LOCATOR_SET_DUMP, mp);
18118
18119   mp->filter = filter;
18120
18121   /* send it... */
18122   S (mp);
18123
18124   /* Use a control ping for synchronization */
18125   MPING (CONTROL_PING, mp_ping);
18126   S (mp_ping);
18127
18128   /* Wait for a reply... */
18129   W (ret);
18130   return ret;
18131 }
18132
18133 #define api_lisp_locator_set_dump api_one_locator_set_dump
18134
18135 static int
18136 api_one_eid_table_map_dump (vat_main_t * vam)
18137 {
18138   u8 is_l2 = 0;
18139   u8 mode_set = 0;
18140   unformat_input_t *input = vam->input;
18141   vl_api_one_eid_table_map_dump_t *mp;
18142   vl_api_control_ping_t *mp_ping;
18143   int ret;
18144
18145   /* Parse args required to build the message */
18146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18147     {
18148       if (unformat (input, "l2"))
18149         {
18150           is_l2 = 1;
18151           mode_set = 1;
18152         }
18153       else if (unformat (input, "l3"))
18154         {
18155           is_l2 = 0;
18156           mode_set = 1;
18157         }
18158       else
18159         {
18160           errmsg ("parse error '%U'", format_unformat_error, input);
18161           return -99;
18162         }
18163     }
18164
18165   if (!mode_set)
18166     {
18167       errmsg ("expected one of 'l2' or 'l3' parameter!");
18168       return -99;
18169     }
18170
18171   if (!vam->json_output)
18172     {
18173       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18174     }
18175
18176   M (ONE_EID_TABLE_MAP_DUMP, mp);
18177   mp->is_l2 = is_l2;
18178
18179   /* send it... */
18180   S (mp);
18181
18182   /* Use a control ping for synchronization */
18183   MPING (CONTROL_PING, mp_ping);
18184   S (mp_ping);
18185
18186   /* Wait for a reply... */
18187   W (ret);
18188   return ret;
18189 }
18190
18191 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18192
18193 static int
18194 api_one_eid_table_vni_dump (vat_main_t * vam)
18195 {
18196   vl_api_one_eid_table_vni_dump_t *mp;
18197   vl_api_control_ping_t *mp_ping;
18198   int ret;
18199
18200   if (!vam->json_output)
18201     {
18202       print (vam->ofp, "VNI");
18203     }
18204
18205   M (ONE_EID_TABLE_VNI_DUMP, mp);
18206
18207   /* send it... */
18208   S (mp);
18209
18210   /* Use a control ping for synchronization */
18211   MPING (CONTROL_PING, mp_ping);
18212   S (mp_ping);
18213
18214   /* Wait for a reply... */
18215   W (ret);
18216   return ret;
18217 }
18218
18219 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18220
18221 static int
18222 api_one_eid_table_dump (vat_main_t * vam)
18223 {
18224   unformat_input_t *i = vam->input;
18225   vl_api_one_eid_table_dump_t *mp;
18226   vl_api_control_ping_t *mp_ping;
18227   struct in_addr ip4;
18228   struct in6_addr ip6;
18229   u8 mac[6];
18230   u8 eid_type = ~0, eid_set = 0;
18231   u32 prefix_length = ~0, t, vni = 0;
18232   u8 filter = 0;
18233   int ret;
18234   lisp_nsh_api_t nsh;
18235
18236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18237     {
18238       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18239         {
18240           eid_set = 1;
18241           eid_type = 0;
18242           prefix_length = t;
18243         }
18244       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18245         {
18246           eid_set = 1;
18247           eid_type = 1;
18248           prefix_length = t;
18249         }
18250       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18251         {
18252           eid_set = 1;
18253           eid_type = 2;
18254         }
18255       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18256         {
18257           eid_set = 1;
18258           eid_type = 3;
18259         }
18260       else if (unformat (i, "vni %d", &t))
18261         {
18262           vni = t;
18263         }
18264       else if (unformat (i, "local"))
18265         {
18266           filter = 1;
18267         }
18268       else if (unformat (i, "remote"))
18269         {
18270           filter = 2;
18271         }
18272       else
18273         {
18274           errmsg ("parse error '%U'", format_unformat_error, i);
18275           return -99;
18276         }
18277     }
18278
18279   if (!vam->json_output)
18280     {
18281       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18282              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18283     }
18284
18285   M (ONE_EID_TABLE_DUMP, mp);
18286
18287   mp->filter = filter;
18288   if (eid_set)
18289     {
18290       mp->eid_set = 1;
18291       mp->vni = htonl (vni);
18292       mp->eid_type = eid_type;
18293       switch (eid_type)
18294         {
18295         case 0:
18296           mp->prefix_length = prefix_length;
18297           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18298           break;
18299         case 1:
18300           mp->prefix_length = prefix_length;
18301           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18302           break;
18303         case 2:
18304           clib_memcpy (mp->eid, mac, sizeof (mac));
18305           break;
18306         case 3:
18307           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18308           break;
18309         default:
18310           errmsg ("unknown EID type %d!", eid_type);
18311           return -99;
18312         }
18313     }
18314
18315   /* send it... */
18316   S (mp);
18317
18318   /* Use a control ping for synchronization */
18319   MPING (CONTROL_PING, mp_ping);
18320   S (mp_ping);
18321
18322   /* Wait for a reply... */
18323   W (ret);
18324   return ret;
18325 }
18326
18327 #define api_lisp_eid_table_dump api_one_eid_table_dump
18328
18329 static int
18330 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18331 {
18332   unformat_input_t *i = vam->input;
18333   vl_api_gpe_fwd_entries_get_t *mp;
18334   u8 vni_set = 0;
18335   u32 vni = ~0;
18336   int ret;
18337
18338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18339     {
18340       if (unformat (i, "vni %d", &vni))
18341         {
18342           vni_set = 1;
18343         }
18344       else
18345         {
18346           errmsg ("parse error '%U'", format_unformat_error, i);
18347           return -99;
18348         }
18349     }
18350
18351   if (!vni_set)
18352     {
18353       errmsg ("vni not set!");
18354       return -99;
18355     }
18356
18357   if (!vam->json_output)
18358     {
18359       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18360              "leid", "reid");
18361     }
18362
18363   M (GPE_FWD_ENTRIES_GET, mp);
18364   mp->vni = clib_host_to_net_u32 (vni);
18365
18366   /* send it... */
18367   S (mp);
18368
18369   /* Wait for a reply... */
18370   W (ret);
18371   return ret;
18372 }
18373
18374 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18375 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18376 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18377 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18378 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18379 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18380 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18381 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18382
18383 static int
18384 api_one_adjacencies_get (vat_main_t * vam)
18385 {
18386   unformat_input_t *i = vam->input;
18387   vl_api_one_adjacencies_get_t *mp;
18388   u8 vni_set = 0;
18389   u32 vni = ~0;
18390   int ret;
18391
18392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18393     {
18394       if (unformat (i, "vni %d", &vni))
18395         {
18396           vni_set = 1;
18397         }
18398       else
18399         {
18400           errmsg ("parse error '%U'", format_unformat_error, i);
18401           return -99;
18402         }
18403     }
18404
18405   if (!vni_set)
18406     {
18407       errmsg ("vni not set!");
18408       return -99;
18409     }
18410
18411   if (!vam->json_output)
18412     {
18413       print (vam->ofp, "%s %40s", "leid", "reid");
18414     }
18415
18416   M (ONE_ADJACENCIES_GET, mp);
18417   mp->vni = clib_host_to_net_u32 (vni);
18418
18419   /* send it... */
18420   S (mp);
18421
18422   /* Wait for a reply... */
18423   W (ret);
18424   return ret;
18425 }
18426
18427 #define api_lisp_adjacencies_get api_one_adjacencies_get
18428
18429 static int
18430 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18431 {
18432   unformat_input_t *i = vam->input;
18433   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18434   int ret;
18435   u8 ip_family_set = 0, is_ip4 = 1;
18436
18437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18438     {
18439       if (unformat (i, "ip4"))
18440         {
18441           ip_family_set = 1;
18442           is_ip4 = 1;
18443         }
18444       else if (unformat (i, "ip6"))
18445         {
18446           ip_family_set = 1;
18447           is_ip4 = 0;
18448         }
18449       else
18450         {
18451           errmsg ("parse error '%U'", format_unformat_error, i);
18452           return -99;
18453         }
18454     }
18455
18456   if (!ip_family_set)
18457     {
18458       errmsg ("ip family not set!");
18459       return -99;
18460     }
18461
18462   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18463   mp->is_ip4 = is_ip4;
18464
18465   /* send it... */
18466   S (mp);
18467
18468   /* Wait for a reply... */
18469   W (ret);
18470   return ret;
18471 }
18472
18473 static int
18474 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18475 {
18476   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18477   int ret;
18478
18479   if (!vam->json_output)
18480     {
18481       print (vam->ofp, "VNIs");
18482     }
18483
18484   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18485
18486   /* send it... */
18487   S (mp);
18488
18489   /* Wait for a reply... */
18490   W (ret);
18491   return ret;
18492 }
18493
18494 static int
18495 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18496 {
18497   unformat_input_t *i = vam->input;
18498   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18499   int ret = 0;
18500   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18501   struct in_addr ip4;
18502   struct in6_addr ip6;
18503   u32 table_id = 0, nh_sw_if_index = ~0;
18504
18505   memset (&ip4, 0, sizeof (ip4));
18506   memset (&ip6, 0, sizeof (ip6));
18507
18508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18509     {
18510       if (unformat (i, "del"))
18511         is_add = 0;
18512       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18513                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18514         {
18515           ip_set = 1;
18516           is_ip4 = 1;
18517         }
18518       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18519                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18520         {
18521           ip_set = 1;
18522           is_ip4 = 0;
18523         }
18524       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18525         {
18526           ip_set = 1;
18527           is_ip4 = 1;
18528           nh_sw_if_index = ~0;
18529         }
18530       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18531         {
18532           ip_set = 1;
18533           is_ip4 = 0;
18534           nh_sw_if_index = ~0;
18535         }
18536       else if (unformat (i, "table %d", &table_id))
18537         ;
18538       else
18539         {
18540           errmsg ("parse error '%U'", format_unformat_error, i);
18541           return -99;
18542         }
18543     }
18544
18545   if (!ip_set)
18546     {
18547       errmsg ("nh addr not set!");
18548       return -99;
18549     }
18550
18551   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18552   mp->is_add = is_add;
18553   mp->table_id = clib_host_to_net_u32 (table_id);
18554   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18555   mp->is_ip4 = is_ip4;
18556   if (is_ip4)
18557     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18558   else
18559     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18560
18561   /* send it... */
18562   S (mp);
18563
18564   /* Wait for a reply... */
18565   W (ret);
18566   return ret;
18567 }
18568
18569 static int
18570 api_one_map_server_dump (vat_main_t * vam)
18571 {
18572   vl_api_one_map_server_dump_t *mp;
18573   vl_api_control_ping_t *mp_ping;
18574   int ret;
18575
18576   if (!vam->json_output)
18577     {
18578       print (vam->ofp, "%=20s", "Map server");
18579     }
18580
18581   M (ONE_MAP_SERVER_DUMP, mp);
18582   /* send it... */
18583   S (mp);
18584
18585   /* Use a control ping for synchronization */
18586   MPING (CONTROL_PING, mp_ping);
18587   S (mp_ping);
18588
18589   /* Wait for a reply... */
18590   W (ret);
18591   return ret;
18592 }
18593
18594 #define api_lisp_map_server_dump api_one_map_server_dump
18595
18596 static int
18597 api_one_map_resolver_dump (vat_main_t * vam)
18598 {
18599   vl_api_one_map_resolver_dump_t *mp;
18600   vl_api_control_ping_t *mp_ping;
18601   int ret;
18602
18603   if (!vam->json_output)
18604     {
18605       print (vam->ofp, "%=20s", "Map resolver");
18606     }
18607
18608   M (ONE_MAP_RESOLVER_DUMP, mp);
18609   /* send it... */
18610   S (mp);
18611
18612   /* Use a control ping for synchronization */
18613   MPING (CONTROL_PING, mp_ping);
18614   S (mp_ping);
18615
18616   /* Wait for a reply... */
18617   W (ret);
18618   return ret;
18619 }
18620
18621 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18622
18623 static int
18624 api_one_stats_flush (vat_main_t * vam)
18625 {
18626   vl_api_one_stats_flush_t *mp;
18627   int ret = 0;
18628
18629   M (ONE_STATS_FLUSH, mp);
18630   S (mp);
18631   W (ret);
18632   return ret;
18633 }
18634
18635 static int
18636 api_one_stats_dump (vat_main_t * vam)
18637 {
18638   vl_api_one_stats_dump_t *mp;
18639   vl_api_control_ping_t *mp_ping;
18640   int ret;
18641
18642   M (ONE_STATS_DUMP, mp);
18643   /* send it... */
18644   S (mp);
18645
18646   /* Use a control ping for synchronization */
18647   MPING (CONTROL_PING, mp_ping);
18648   S (mp_ping);
18649
18650   /* Wait for a reply... */
18651   W (ret);
18652   return ret;
18653 }
18654
18655 static int
18656 api_show_one_status (vat_main_t * vam)
18657 {
18658   vl_api_show_one_status_t *mp;
18659   int ret;
18660
18661   if (!vam->json_output)
18662     {
18663       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18664     }
18665
18666   M (SHOW_ONE_STATUS, mp);
18667   /* send it... */
18668   S (mp);
18669   /* Wait for a reply... */
18670   W (ret);
18671   return ret;
18672 }
18673
18674 #define api_show_lisp_status api_show_one_status
18675
18676 static int
18677 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18678 {
18679   vl_api_gpe_fwd_entry_path_dump_t *mp;
18680   vl_api_control_ping_t *mp_ping;
18681   unformat_input_t *i = vam->input;
18682   u32 fwd_entry_index = ~0;
18683   int ret;
18684
18685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18686     {
18687       if (unformat (i, "index %d", &fwd_entry_index))
18688         ;
18689       else
18690         break;
18691     }
18692
18693   if (~0 == fwd_entry_index)
18694     {
18695       errmsg ("no index specified!");
18696       return -99;
18697     }
18698
18699   if (!vam->json_output)
18700     {
18701       print (vam->ofp, "first line");
18702     }
18703
18704   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18705
18706   /* send it... */
18707   S (mp);
18708   /* Use a control ping for synchronization */
18709   MPING (CONTROL_PING, mp_ping);
18710   S (mp_ping);
18711
18712   /* Wait for a reply... */
18713   W (ret);
18714   return ret;
18715 }
18716
18717 static int
18718 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18719 {
18720   vl_api_one_get_map_request_itr_rlocs_t *mp;
18721   int ret;
18722
18723   if (!vam->json_output)
18724     {
18725       print (vam->ofp, "%=20s", "itr-rlocs:");
18726     }
18727
18728   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18729   /* send it... */
18730   S (mp);
18731   /* Wait for a reply... */
18732   W (ret);
18733   return ret;
18734 }
18735
18736 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18737
18738 static int
18739 api_af_packet_create (vat_main_t * vam)
18740 {
18741   unformat_input_t *i = vam->input;
18742   vl_api_af_packet_create_t *mp;
18743   u8 *host_if_name = 0;
18744   u8 hw_addr[6];
18745   u8 random_hw_addr = 1;
18746   int ret;
18747
18748   memset (hw_addr, 0, sizeof (hw_addr));
18749
18750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (i, "name %s", &host_if_name))
18753         vec_add1 (host_if_name, 0);
18754       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18755         random_hw_addr = 0;
18756       else
18757         break;
18758     }
18759
18760   if (!vec_len (host_if_name))
18761     {
18762       errmsg ("host-interface name must be specified");
18763       return -99;
18764     }
18765
18766   if (vec_len (host_if_name) > 64)
18767     {
18768       errmsg ("host-interface name too long");
18769       return -99;
18770     }
18771
18772   M (AF_PACKET_CREATE, mp);
18773
18774   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18775   clib_memcpy (mp->hw_addr, hw_addr, 6);
18776   mp->use_random_hw_addr = random_hw_addr;
18777   vec_free (host_if_name);
18778
18779   S (mp);
18780
18781   /* *INDENT-OFF* */
18782   W2 (ret,
18783       ({
18784         if (ret == 0)
18785           fprintf (vam->ofp ? vam->ofp : stderr,
18786                    " new sw_if_index = %d\n", vam->sw_if_index);
18787       }));
18788   /* *INDENT-ON* */
18789   return ret;
18790 }
18791
18792 static int
18793 api_af_packet_delete (vat_main_t * vam)
18794 {
18795   unformat_input_t *i = vam->input;
18796   vl_api_af_packet_delete_t *mp;
18797   u8 *host_if_name = 0;
18798   int ret;
18799
18800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18801     {
18802       if (unformat (i, "name %s", &host_if_name))
18803         vec_add1 (host_if_name, 0);
18804       else
18805         break;
18806     }
18807
18808   if (!vec_len (host_if_name))
18809     {
18810       errmsg ("host-interface name must be specified");
18811       return -99;
18812     }
18813
18814   if (vec_len (host_if_name) > 64)
18815     {
18816       errmsg ("host-interface name too long");
18817       return -99;
18818     }
18819
18820   M (AF_PACKET_DELETE, mp);
18821
18822   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18823   vec_free (host_if_name);
18824
18825   S (mp);
18826   W (ret);
18827   return ret;
18828 }
18829
18830 static int
18831 api_policer_add_del (vat_main_t * vam)
18832 {
18833   unformat_input_t *i = vam->input;
18834   vl_api_policer_add_del_t *mp;
18835   u8 is_add = 1;
18836   u8 *name = 0;
18837   u32 cir = 0;
18838   u32 eir = 0;
18839   u64 cb = 0;
18840   u64 eb = 0;
18841   u8 rate_type = 0;
18842   u8 round_type = 0;
18843   u8 type = 0;
18844   u8 color_aware = 0;
18845   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18846   int ret;
18847
18848   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18849   conform_action.dscp = 0;
18850   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18851   exceed_action.dscp = 0;
18852   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18853   violate_action.dscp = 0;
18854
18855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18856     {
18857       if (unformat (i, "del"))
18858         is_add = 0;
18859       else if (unformat (i, "name %s", &name))
18860         vec_add1 (name, 0);
18861       else if (unformat (i, "cir %u", &cir))
18862         ;
18863       else if (unformat (i, "eir %u", &eir))
18864         ;
18865       else if (unformat (i, "cb %u", &cb))
18866         ;
18867       else if (unformat (i, "eb %u", &eb))
18868         ;
18869       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18870                          &rate_type))
18871         ;
18872       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18873                          &round_type))
18874         ;
18875       else if (unformat (i, "type %U", unformat_policer_type, &type))
18876         ;
18877       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18878                          &conform_action))
18879         ;
18880       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18881                          &exceed_action))
18882         ;
18883       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18884                          &violate_action))
18885         ;
18886       else if (unformat (i, "color-aware"))
18887         color_aware = 1;
18888       else
18889         break;
18890     }
18891
18892   if (!vec_len (name))
18893     {
18894       errmsg ("policer name must be specified");
18895       return -99;
18896     }
18897
18898   if (vec_len (name) > 64)
18899     {
18900       errmsg ("policer name too long");
18901       return -99;
18902     }
18903
18904   M (POLICER_ADD_DEL, mp);
18905
18906   clib_memcpy (mp->name, name, vec_len (name));
18907   vec_free (name);
18908   mp->is_add = is_add;
18909   mp->cir = ntohl (cir);
18910   mp->eir = ntohl (eir);
18911   mp->cb = clib_net_to_host_u64 (cb);
18912   mp->eb = clib_net_to_host_u64 (eb);
18913   mp->rate_type = rate_type;
18914   mp->round_type = round_type;
18915   mp->type = type;
18916   mp->conform_action_type = conform_action.action_type;
18917   mp->conform_dscp = conform_action.dscp;
18918   mp->exceed_action_type = exceed_action.action_type;
18919   mp->exceed_dscp = exceed_action.dscp;
18920   mp->violate_action_type = violate_action.action_type;
18921   mp->violate_dscp = violate_action.dscp;
18922   mp->color_aware = color_aware;
18923
18924   S (mp);
18925   W (ret);
18926   return ret;
18927 }
18928
18929 static int
18930 api_policer_dump (vat_main_t * vam)
18931 {
18932   unformat_input_t *i = vam->input;
18933   vl_api_policer_dump_t *mp;
18934   vl_api_control_ping_t *mp_ping;
18935   u8 *match_name = 0;
18936   u8 match_name_valid = 0;
18937   int ret;
18938
18939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18940     {
18941       if (unformat (i, "name %s", &match_name))
18942         {
18943           vec_add1 (match_name, 0);
18944           match_name_valid = 1;
18945         }
18946       else
18947         break;
18948     }
18949
18950   M (POLICER_DUMP, mp);
18951   mp->match_name_valid = match_name_valid;
18952   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18953   vec_free (match_name);
18954   /* send it... */
18955   S (mp);
18956
18957   /* Use a control ping for synchronization */
18958   MPING (CONTROL_PING, mp_ping);
18959   S (mp_ping);
18960
18961   /* Wait for a reply... */
18962   W (ret);
18963   return ret;
18964 }
18965
18966 static int
18967 api_policer_classify_set_interface (vat_main_t * vam)
18968 {
18969   unformat_input_t *i = vam->input;
18970   vl_api_policer_classify_set_interface_t *mp;
18971   u32 sw_if_index;
18972   int sw_if_index_set;
18973   u32 ip4_table_index = ~0;
18974   u32 ip6_table_index = ~0;
18975   u32 l2_table_index = ~0;
18976   u8 is_add = 1;
18977   int ret;
18978
18979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18980     {
18981       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18982         sw_if_index_set = 1;
18983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18984         sw_if_index_set = 1;
18985       else if (unformat (i, "del"))
18986         is_add = 0;
18987       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18988         ;
18989       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18990         ;
18991       else if (unformat (i, "l2-table %d", &l2_table_index))
18992         ;
18993       else
18994         {
18995           clib_warning ("parse error '%U'", format_unformat_error, i);
18996           return -99;
18997         }
18998     }
18999
19000   if (sw_if_index_set == 0)
19001     {
19002       errmsg ("missing interface name or sw_if_index");
19003       return -99;
19004     }
19005
19006   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19007
19008   mp->sw_if_index = ntohl (sw_if_index);
19009   mp->ip4_table_index = ntohl (ip4_table_index);
19010   mp->ip6_table_index = ntohl (ip6_table_index);
19011   mp->l2_table_index = ntohl (l2_table_index);
19012   mp->is_add = is_add;
19013
19014   S (mp);
19015   W (ret);
19016   return ret;
19017 }
19018
19019 static int
19020 api_policer_classify_dump (vat_main_t * vam)
19021 {
19022   unformat_input_t *i = vam->input;
19023   vl_api_policer_classify_dump_t *mp;
19024   vl_api_control_ping_t *mp_ping;
19025   u8 type = POLICER_CLASSIFY_N_TABLES;
19026   int ret;
19027
19028   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19029     ;
19030   else
19031     {
19032       errmsg ("classify table type must be specified");
19033       return -99;
19034     }
19035
19036   if (!vam->json_output)
19037     {
19038       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19039     }
19040
19041   M (POLICER_CLASSIFY_DUMP, mp);
19042   mp->type = type;
19043   /* send it... */
19044   S (mp);
19045
19046   /* Use a control ping for synchronization */
19047   MPING (CONTROL_PING, mp_ping);
19048   S (mp_ping);
19049
19050   /* Wait for a reply... */
19051   W (ret);
19052   return ret;
19053 }
19054
19055 static int
19056 api_netmap_create (vat_main_t * vam)
19057 {
19058   unformat_input_t *i = vam->input;
19059   vl_api_netmap_create_t *mp;
19060   u8 *if_name = 0;
19061   u8 hw_addr[6];
19062   u8 random_hw_addr = 1;
19063   u8 is_pipe = 0;
19064   u8 is_master = 0;
19065   int ret;
19066
19067   memset (hw_addr, 0, sizeof (hw_addr));
19068
19069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19070     {
19071       if (unformat (i, "name %s", &if_name))
19072         vec_add1 (if_name, 0);
19073       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19074         random_hw_addr = 0;
19075       else if (unformat (i, "pipe"))
19076         is_pipe = 1;
19077       else if (unformat (i, "master"))
19078         is_master = 1;
19079       else if (unformat (i, "slave"))
19080         is_master = 0;
19081       else
19082         break;
19083     }
19084
19085   if (!vec_len (if_name))
19086     {
19087       errmsg ("interface name must be specified");
19088       return -99;
19089     }
19090
19091   if (vec_len (if_name) > 64)
19092     {
19093       errmsg ("interface name too long");
19094       return -99;
19095     }
19096
19097   M (NETMAP_CREATE, mp);
19098
19099   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19100   clib_memcpy (mp->hw_addr, hw_addr, 6);
19101   mp->use_random_hw_addr = random_hw_addr;
19102   mp->is_pipe = is_pipe;
19103   mp->is_master = is_master;
19104   vec_free (if_name);
19105
19106   S (mp);
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static int
19112 api_netmap_delete (vat_main_t * vam)
19113 {
19114   unformat_input_t *i = vam->input;
19115   vl_api_netmap_delete_t *mp;
19116   u8 *if_name = 0;
19117   int ret;
19118
19119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19120     {
19121       if (unformat (i, "name %s", &if_name))
19122         vec_add1 (if_name, 0);
19123       else
19124         break;
19125     }
19126
19127   if (!vec_len (if_name))
19128     {
19129       errmsg ("interface name must be specified");
19130       return -99;
19131     }
19132
19133   if (vec_len (if_name) > 64)
19134     {
19135       errmsg ("interface name too long");
19136       return -99;
19137     }
19138
19139   M (NETMAP_DELETE, mp);
19140
19141   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19142   vec_free (if_name);
19143
19144   S (mp);
19145   W (ret);
19146   return ret;
19147 }
19148
19149 static void
19150 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19151 {
19152   if (fp->afi == IP46_TYPE_IP6)
19153     print (vam->ofp,
19154            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19155            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19156            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19157            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19158            format_ip6_address, fp->next_hop);
19159   else if (fp->afi == IP46_TYPE_IP4)
19160     print (vam->ofp,
19161            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19162            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19163            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19164            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19165            format_ip4_address, fp->next_hop);
19166 }
19167
19168 static void
19169 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19170                                  vl_api_fib_path2_t * fp)
19171 {
19172   struct in_addr ip4;
19173   struct in6_addr ip6;
19174
19175   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19176   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19177   vat_json_object_add_uint (node, "is_local", fp->is_local);
19178   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19179   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19180   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19181   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19182   if (fp->afi == IP46_TYPE_IP4)
19183     {
19184       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19185       vat_json_object_add_ip4 (node, "next_hop", ip4);
19186     }
19187   else if (fp->afi == IP46_TYPE_IP6)
19188     {
19189       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19190       vat_json_object_add_ip6 (node, "next_hop", ip6);
19191     }
19192 }
19193
19194 static void
19195 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19196 {
19197   vat_main_t *vam = &vat_main;
19198   int count = ntohl (mp->mt_count);
19199   vl_api_fib_path2_t *fp;
19200   i32 i;
19201
19202   print (vam->ofp, "[%d]: sw_if_index %d via:",
19203          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19204   fp = mp->mt_paths;
19205   for (i = 0; i < count; i++)
19206     {
19207       vl_api_mpls_fib_path_print (vam, fp);
19208       fp++;
19209     }
19210
19211   print (vam->ofp, "");
19212 }
19213
19214 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19215 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19216
19217 static void
19218 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19219 {
19220   vat_main_t *vam = &vat_main;
19221   vat_json_node_t *node = NULL;
19222   int count = ntohl (mp->mt_count);
19223   vl_api_fib_path2_t *fp;
19224   i32 i;
19225
19226   if (VAT_JSON_ARRAY != vam->json_tree.type)
19227     {
19228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19229       vat_json_init_array (&vam->json_tree);
19230     }
19231   node = vat_json_array_add (&vam->json_tree);
19232
19233   vat_json_init_object (node);
19234   vat_json_object_add_uint (node, "tunnel_index",
19235                             ntohl (mp->mt_tunnel_index));
19236   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19237
19238   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19239
19240   fp = mp->mt_paths;
19241   for (i = 0; i < count; i++)
19242     {
19243       vl_api_mpls_fib_path_json_print (node, fp);
19244       fp++;
19245     }
19246 }
19247
19248 static int
19249 api_mpls_tunnel_dump (vat_main_t * vam)
19250 {
19251   vl_api_mpls_tunnel_dump_t *mp;
19252   vl_api_control_ping_t *mp_ping;
19253   i32 index = -1;
19254   int ret;
19255
19256   /* Parse args required to build the message */
19257   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19258     {
19259       if (!unformat (vam->input, "tunnel_index %d", &index))
19260         {
19261           index = -1;
19262           break;
19263         }
19264     }
19265
19266   print (vam->ofp, "  tunnel_index %d", index);
19267
19268   M (MPLS_TUNNEL_DUMP, mp);
19269   mp->tunnel_index = htonl (index);
19270   S (mp);
19271
19272   /* Use a control ping for synchronization */
19273   MPING (CONTROL_PING, mp_ping);
19274   S (mp_ping);
19275
19276   W (ret);
19277   return ret;
19278 }
19279
19280 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19281 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19282
19283
19284 static void
19285 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19286 {
19287   vat_main_t *vam = &vat_main;
19288   int count = ntohl (mp->count);
19289   vl_api_fib_path2_t *fp;
19290   int i;
19291
19292   print (vam->ofp,
19293          "table-id %d, label %u, ess_bit %u",
19294          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19295   fp = mp->path;
19296   for (i = 0; i < count; i++)
19297     {
19298       vl_api_mpls_fib_path_print (vam, fp);
19299       fp++;
19300     }
19301 }
19302
19303 static void vl_api_mpls_fib_details_t_handler_json
19304   (vl_api_mpls_fib_details_t * mp)
19305 {
19306   vat_main_t *vam = &vat_main;
19307   int count = ntohl (mp->count);
19308   vat_json_node_t *node = NULL;
19309   vl_api_fib_path2_t *fp;
19310   int i;
19311
19312   if (VAT_JSON_ARRAY != vam->json_tree.type)
19313     {
19314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19315       vat_json_init_array (&vam->json_tree);
19316     }
19317   node = vat_json_array_add (&vam->json_tree);
19318
19319   vat_json_init_object (node);
19320   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19321   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19322   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19323   vat_json_object_add_uint (node, "path_count", count);
19324   fp = mp->path;
19325   for (i = 0; i < count; i++)
19326     {
19327       vl_api_mpls_fib_path_json_print (node, fp);
19328       fp++;
19329     }
19330 }
19331
19332 static int
19333 api_mpls_fib_dump (vat_main_t * vam)
19334 {
19335   vl_api_mpls_fib_dump_t *mp;
19336   vl_api_control_ping_t *mp_ping;
19337   int ret;
19338
19339   M (MPLS_FIB_DUMP, mp);
19340   S (mp);
19341
19342   /* Use a control ping for synchronization */
19343   MPING (CONTROL_PING, mp_ping);
19344   S (mp_ping);
19345
19346   W (ret);
19347   return ret;
19348 }
19349
19350 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19351 #define vl_api_ip_fib_details_t_print vl_noop_handler
19352
19353 static void
19354 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19355 {
19356   vat_main_t *vam = &vat_main;
19357   int count = ntohl (mp->count);
19358   vl_api_fib_path_t *fp;
19359   int i;
19360
19361   print (vam->ofp,
19362          "table-id %d, prefix %U/%d",
19363          ntohl (mp->table_id), format_ip4_address, mp->address,
19364          mp->address_length);
19365   fp = mp->path;
19366   for (i = 0; i < count; i++)
19367     {
19368       if (fp->afi == IP46_TYPE_IP6)
19369         print (vam->ofp,
19370                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19371                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19372                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19373                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19374                format_ip6_address, fp->next_hop);
19375       else if (fp->afi == IP46_TYPE_IP4)
19376         print (vam->ofp,
19377                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19378                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19379                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19380                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19381                format_ip4_address, fp->next_hop);
19382       fp++;
19383     }
19384 }
19385
19386 static void vl_api_ip_fib_details_t_handler_json
19387   (vl_api_ip_fib_details_t * mp)
19388 {
19389   vat_main_t *vam = &vat_main;
19390   int count = ntohl (mp->count);
19391   vat_json_node_t *node = NULL;
19392   struct in_addr ip4;
19393   struct in6_addr ip6;
19394   vl_api_fib_path_t *fp;
19395   int i;
19396
19397   if (VAT_JSON_ARRAY != vam->json_tree.type)
19398     {
19399       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19400       vat_json_init_array (&vam->json_tree);
19401     }
19402   node = vat_json_array_add (&vam->json_tree);
19403
19404   vat_json_init_object (node);
19405   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19406   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19407   vat_json_object_add_ip4 (node, "prefix", ip4);
19408   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19409   vat_json_object_add_uint (node, "path_count", count);
19410   fp = mp->path;
19411   for (i = 0; i < count; i++)
19412     {
19413       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19414       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19415       vat_json_object_add_uint (node, "is_local", fp->is_local);
19416       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19417       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19418       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19419       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19420       if (fp->afi == IP46_TYPE_IP4)
19421         {
19422           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19423           vat_json_object_add_ip4 (node, "next_hop", ip4);
19424         }
19425       else if (fp->afi == IP46_TYPE_IP6)
19426         {
19427           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19428           vat_json_object_add_ip6 (node, "next_hop", ip6);
19429         }
19430     }
19431 }
19432
19433 static int
19434 api_ip_fib_dump (vat_main_t * vam)
19435 {
19436   vl_api_ip_fib_dump_t *mp;
19437   vl_api_control_ping_t *mp_ping;
19438   int ret;
19439
19440   M (IP_FIB_DUMP, mp);
19441   S (mp);
19442
19443   /* Use a control ping for synchronization */
19444   MPING (CONTROL_PING, mp_ping);
19445   S (mp_ping);
19446
19447   W (ret);
19448   return ret;
19449 }
19450
19451 static int
19452 api_ip_mfib_dump (vat_main_t * vam)
19453 {
19454   vl_api_ip_mfib_dump_t *mp;
19455   vl_api_control_ping_t *mp_ping;
19456   int ret;
19457
19458   M (IP_MFIB_DUMP, mp);
19459   S (mp);
19460
19461   /* Use a control ping for synchronization */
19462   MPING (CONTROL_PING, mp_ping);
19463   S (mp_ping);
19464
19465   W (ret);
19466   return ret;
19467 }
19468
19469 static void vl_api_ip_neighbor_details_t_handler
19470   (vl_api_ip_neighbor_details_t * mp)
19471 {
19472   vat_main_t *vam = &vat_main;
19473
19474   print (vam->ofp, "%c %U %U",
19475          (mp->is_static) ? 'S' : 'D',
19476          format_ethernet_address, &mp->mac_address,
19477          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19478          &mp->ip_address);
19479 }
19480
19481 static void vl_api_ip_neighbor_details_t_handler_json
19482   (vl_api_ip_neighbor_details_t * mp)
19483 {
19484
19485   vat_main_t *vam = &vat_main;
19486   vat_json_node_t *node;
19487   struct in_addr ip4;
19488   struct in6_addr ip6;
19489
19490   if (VAT_JSON_ARRAY != vam->json_tree.type)
19491     {
19492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19493       vat_json_init_array (&vam->json_tree);
19494     }
19495   node = vat_json_array_add (&vam->json_tree);
19496
19497   vat_json_init_object (node);
19498   vat_json_object_add_string_copy (node, "flag",
19499                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19500                                    "dynamic");
19501
19502   vat_json_object_add_string_copy (node, "link_layer",
19503                                    format (0, "%U", format_ethernet_address,
19504                                            &mp->mac_address));
19505
19506   if (mp->is_ipv6)
19507     {
19508       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19509       vat_json_object_add_ip6 (node, "ip_address", ip6);
19510     }
19511   else
19512     {
19513       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19514       vat_json_object_add_ip4 (node, "ip_address", ip4);
19515     }
19516 }
19517
19518 static int
19519 api_ip_neighbor_dump (vat_main_t * vam)
19520 {
19521   unformat_input_t *i = vam->input;
19522   vl_api_ip_neighbor_dump_t *mp;
19523   vl_api_control_ping_t *mp_ping;
19524   u8 is_ipv6 = 0;
19525   u32 sw_if_index = ~0;
19526   int ret;
19527
19528   /* Parse args required to build the message */
19529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19530     {
19531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19532         ;
19533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19534         ;
19535       else if (unformat (i, "ip6"))
19536         is_ipv6 = 1;
19537       else
19538         break;
19539     }
19540
19541   if (sw_if_index == ~0)
19542     {
19543       errmsg ("missing interface name or sw_if_index");
19544       return -99;
19545     }
19546
19547   M (IP_NEIGHBOR_DUMP, mp);
19548   mp->is_ipv6 = (u8) is_ipv6;
19549   mp->sw_if_index = ntohl (sw_if_index);
19550   S (mp);
19551
19552   /* Use a control ping for synchronization */
19553   MPING (CONTROL_PING, mp_ping);
19554   S (mp_ping);
19555
19556   W (ret);
19557   return ret;
19558 }
19559
19560 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19561 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19562
19563 static void
19564 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19565 {
19566   vat_main_t *vam = &vat_main;
19567   int count = ntohl (mp->count);
19568   vl_api_fib_path_t *fp;
19569   int i;
19570
19571   print (vam->ofp,
19572          "table-id %d, prefix %U/%d",
19573          ntohl (mp->table_id), format_ip6_address, mp->address,
19574          mp->address_length);
19575   fp = mp->path;
19576   for (i = 0; i < count; i++)
19577     {
19578       if (fp->afi == IP46_TYPE_IP6)
19579         print (vam->ofp,
19580                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19581                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19582                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19583                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19584                format_ip6_address, fp->next_hop);
19585       else if (fp->afi == IP46_TYPE_IP4)
19586         print (vam->ofp,
19587                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19588                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19589                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19590                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19591                format_ip4_address, fp->next_hop);
19592       fp++;
19593     }
19594 }
19595
19596 static void vl_api_ip6_fib_details_t_handler_json
19597   (vl_api_ip6_fib_details_t * mp)
19598 {
19599   vat_main_t *vam = &vat_main;
19600   int count = ntohl (mp->count);
19601   vat_json_node_t *node = NULL;
19602   struct in_addr ip4;
19603   struct in6_addr ip6;
19604   vl_api_fib_path_t *fp;
19605   int i;
19606
19607   if (VAT_JSON_ARRAY != vam->json_tree.type)
19608     {
19609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19610       vat_json_init_array (&vam->json_tree);
19611     }
19612   node = vat_json_array_add (&vam->json_tree);
19613
19614   vat_json_init_object (node);
19615   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19616   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19617   vat_json_object_add_ip6 (node, "prefix", ip6);
19618   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19619   vat_json_object_add_uint (node, "path_count", count);
19620   fp = mp->path;
19621   for (i = 0; i < count; i++)
19622     {
19623       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19624       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19625       vat_json_object_add_uint (node, "is_local", fp->is_local);
19626       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19627       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19628       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19629       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19630       if (fp->afi == IP46_TYPE_IP4)
19631         {
19632           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19633           vat_json_object_add_ip4 (node, "next_hop", ip4);
19634         }
19635       else if (fp->afi == IP46_TYPE_IP6)
19636         {
19637           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19638           vat_json_object_add_ip6 (node, "next_hop", ip6);
19639         }
19640     }
19641 }
19642
19643 static int
19644 api_ip6_fib_dump (vat_main_t * vam)
19645 {
19646   vl_api_ip6_fib_dump_t *mp;
19647   vl_api_control_ping_t *mp_ping;
19648   int ret;
19649
19650   M (IP6_FIB_DUMP, mp);
19651   S (mp);
19652
19653   /* Use a control ping for synchronization */
19654   MPING (CONTROL_PING, mp_ping);
19655   S (mp_ping);
19656
19657   W (ret);
19658   return ret;
19659 }
19660
19661 static int
19662 api_ip6_mfib_dump (vat_main_t * vam)
19663 {
19664   vl_api_ip6_mfib_dump_t *mp;
19665   vl_api_control_ping_t *mp_ping;
19666   int ret;
19667
19668   M (IP6_MFIB_DUMP, mp);
19669   S (mp);
19670
19671   /* Use a control ping for synchronization */
19672   MPING (CONTROL_PING, mp_ping);
19673   S (mp_ping);
19674
19675   W (ret);
19676   return ret;
19677 }
19678
19679 int
19680 api_classify_table_ids (vat_main_t * vam)
19681 {
19682   vl_api_classify_table_ids_t *mp;
19683   int ret;
19684
19685   /* Construct the API message */
19686   M (CLASSIFY_TABLE_IDS, mp);
19687   mp->context = 0;
19688
19689   S (mp);
19690   W (ret);
19691   return ret;
19692 }
19693
19694 int
19695 api_classify_table_by_interface (vat_main_t * vam)
19696 {
19697   unformat_input_t *input = vam->input;
19698   vl_api_classify_table_by_interface_t *mp;
19699
19700   u32 sw_if_index = ~0;
19701   int ret;
19702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19703     {
19704       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19705         ;
19706       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19707         ;
19708       else
19709         break;
19710     }
19711   if (sw_if_index == ~0)
19712     {
19713       errmsg ("missing interface name or sw_if_index");
19714       return -99;
19715     }
19716
19717   /* Construct the API message */
19718   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19719   mp->context = 0;
19720   mp->sw_if_index = ntohl (sw_if_index);
19721
19722   S (mp);
19723   W (ret);
19724   return ret;
19725 }
19726
19727 int
19728 api_classify_table_info (vat_main_t * vam)
19729 {
19730   unformat_input_t *input = vam->input;
19731   vl_api_classify_table_info_t *mp;
19732
19733   u32 table_id = ~0;
19734   int ret;
19735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19736     {
19737       if (unformat (input, "table_id %d", &table_id))
19738         ;
19739       else
19740         break;
19741     }
19742   if (table_id == ~0)
19743     {
19744       errmsg ("missing table id");
19745       return -99;
19746     }
19747
19748   /* Construct the API message */
19749   M (CLASSIFY_TABLE_INFO, mp);
19750   mp->context = 0;
19751   mp->table_id = ntohl (table_id);
19752
19753   S (mp);
19754   W (ret);
19755   return ret;
19756 }
19757
19758 int
19759 api_classify_session_dump (vat_main_t * vam)
19760 {
19761   unformat_input_t *input = vam->input;
19762   vl_api_classify_session_dump_t *mp;
19763   vl_api_control_ping_t *mp_ping;
19764
19765   u32 table_id = ~0;
19766   int ret;
19767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19768     {
19769       if (unformat (input, "table_id %d", &table_id))
19770         ;
19771       else
19772         break;
19773     }
19774   if (table_id == ~0)
19775     {
19776       errmsg ("missing table id");
19777       return -99;
19778     }
19779
19780   /* Construct the API message */
19781   M (CLASSIFY_SESSION_DUMP, mp);
19782   mp->context = 0;
19783   mp->table_id = ntohl (table_id);
19784   S (mp);
19785
19786   /* Use a control ping for synchronization */
19787   MPING (CONTROL_PING, mp_ping);
19788   S (mp_ping);
19789
19790   W (ret);
19791   return ret;
19792 }
19793
19794 static void
19795 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19796 {
19797   vat_main_t *vam = &vat_main;
19798
19799   print (vam->ofp, "collector_address %U, collector_port %d, "
19800          "src_address %U, vrf_id %d, path_mtu %u, "
19801          "template_interval %u, udp_checksum %d",
19802          format_ip4_address, mp->collector_address,
19803          ntohs (mp->collector_port),
19804          format_ip4_address, mp->src_address,
19805          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19806          ntohl (mp->template_interval), mp->udp_checksum);
19807
19808   vam->retval = 0;
19809   vam->result_ready = 1;
19810 }
19811
19812 static void
19813   vl_api_ipfix_exporter_details_t_handler_json
19814   (vl_api_ipfix_exporter_details_t * mp)
19815 {
19816   vat_main_t *vam = &vat_main;
19817   vat_json_node_t node;
19818   struct in_addr collector_address;
19819   struct in_addr src_address;
19820
19821   vat_json_init_object (&node);
19822   clib_memcpy (&collector_address, &mp->collector_address,
19823                sizeof (collector_address));
19824   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19825   vat_json_object_add_uint (&node, "collector_port",
19826                             ntohs (mp->collector_port));
19827   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19828   vat_json_object_add_ip4 (&node, "src_address", src_address);
19829   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19830   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19831   vat_json_object_add_uint (&node, "template_interval",
19832                             ntohl (mp->template_interval));
19833   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19834
19835   vat_json_print (vam->ofp, &node);
19836   vat_json_free (&node);
19837   vam->retval = 0;
19838   vam->result_ready = 1;
19839 }
19840
19841 int
19842 api_ipfix_exporter_dump (vat_main_t * vam)
19843 {
19844   vl_api_ipfix_exporter_dump_t *mp;
19845   int ret;
19846
19847   /* Construct the API message */
19848   M (IPFIX_EXPORTER_DUMP, mp);
19849   mp->context = 0;
19850
19851   S (mp);
19852   W (ret);
19853   return ret;
19854 }
19855
19856 static int
19857 api_ipfix_classify_stream_dump (vat_main_t * vam)
19858 {
19859   vl_api_ipfix_classify_stream_dump_t *mp;
19860   int ret;
19861
19862   /* Construct the API message */
19863   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19864   mp->context = 0;
19865
19866   S (mp);
19867   W (ret);
19868   return ret;
19869   /* NOTREACHED */
19870   return 0;
19871 }
19872
19873 static void
19874   vl_api_ipfix_classify_stream_details_t_handler
19875   (vl_api_ipfix_classify_stream_details_t * mp)
19876 {
19877   vat_main_t *vam = &vat_main;
19878   print (vam->ofp, "domain_id %d, src_port %d",
19879          ntohl (mp->domain_id), ntohs (mp->src_port));
19880   vam->retval = 0;
19881   vam->result_ready = 1;
19882 }
19883
19884 static void
19885   vl_api_ipfix_classify_stream_details_t_handler_json
19886   (vl_api_ipfix_classify_stream_details_t * mp)
19887 {
19888   vat_main_t *vam = &vat_main;
19889   vat_json_node_t node;
19890
19891   vat_json_init_object (&node);
19892   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19893   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19894
19895   vat_json_print (vam->ofp, &node);
19896   vat_json_free (&node);
19897   vam->retval = 0;
19898   vam->result_ready = 1;
19899 }
19900
19901 static int
19902 api_ipfix_classify_table_dump (vat_main_t * vam)
19903 {
19904   vl_api_ipfix_classify_table_dump_t *mp;
19905   vl_api_control_ping_t *mp_ping;
19906   int ret;
19907
19908   if (!vam->json_output)
19909     {
19910       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19911              "transport_protocol");
19912     }
19913
19914   /* Construct the API message */
19915   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19916
19917   /* send it... */
19918   S (mp);
19919
19920   /* Use a control ping for synchronization */
19921   MPING (CONTROL_PING, mp_ping);
19922   S (mp_ping);
19923
19924   W (ret);
19925   return ret;
19926 }
19927
19928 static void
19929   vl_api_ipfix_classify_table_details_t_handler
19930   (vl_api_ipfix_classify_table_details_t * mp)
19931 {
19932   vat_main_t *vam = &vat_main;
19933   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19934          mp->transport_protocol);
19935 }
19936
19937 static void
19938   vl_api_ipfix_classify_table_details_t_handler_json
19939   (vl_api_ipfix_classify_table_details_t * mp)
19940 {
19941   vat_json_node_t *node = NULL;
19942   vat_main_t *vam = &vat_main;
19943
19944   if (VAT_JSON_ARRAY != vam->json_tree.type)
19945     {
19946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19947       vat_json_init_array (&vam->json_tree);
19948     }
19949
19950   node = vat_json_array_add (&vam->json_tree);
19951   vat_json_init_object (node);
19952
19953   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19954   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19955   vat_json_object_add_uint (node, "transport_protocol",
19956                             mp->transport_protocol);
19957 }
19958
19959 static int
19960 api_sw_interface_span_enable_disable (vat_main_t * vam)
19961 {
19962   unformat_input_t *i = vam->input;
19963   vl_api_sw_interface_span_enable_disable_t *mp;
19964   u32 src_sw_if_index = ~0;
19965   u32 dst_sw_if_index = ~0;
19966   u8 state = 3;
19967   int ret;
19968   u8 is_l2 = 0;
19969
19970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19971     {
19972       if (unformat
19973           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19974         ;
19975       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19976         ;
19977       else
19978         if (unformat
19979             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19980         ;
19981       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19982         ;
19983       else if (unformat (i, "disable"))
19984         state = 0;
19985       else if (unformat (i, "rx"))
19986         state = 1;
19987       else if (unformat (i, "tx"))
19988         state = 2;
19989       else if (unformat (i, "both"))
19990         state = 3;
19991       else if (unformat (i, "l2"))
19992         is_l2 = 1;
19993       else
19994         break;
19995     }
19996
19997   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19998
19999   mp->sw_if_index_from = htonl (src_sw_if_index);
20000   mp->sw_if_index_to = htonl (dst_sw_if_index);
20001   mp->state = state;
20002   mp->is_l2 = is_l2;
20003
20004   S (mp);
20005   W (ret);
20006   return ret;
20007 }
20008
20009 static void
20010 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20011                                             * mp)
20012 {
20013   vat_main_t *vam = &vat_main;
20014   u8 *sw_if_from_name = 0;
20015   u8 *sw_if_to_name = 0;
20016   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20017   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20018   char *states[] = { "none", "rx", "tx", "both" };
20019   hash_pair_t *p;
20020
20021   /* *INDENT-OFF* */
20022   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20023   ({
20024     if ((u32) p->value[0] == sw_if_index_from)
20025       {
20026         sw_if_from_name = (u8 *)(p->key);
20027         if (sw_if_to_name)
20028           break;
20029       }
20030     if ((u32) p->value[0] == sw_if_index_to)
20031       {
20032         sw_if_to_name = (u8 *)(p->key);
20033         if (sw_if_from_name)
20034           break;
20035       }
20036   }));
20037   /* *INDENT-ON* */
20038   print (vam->ofp, "%20s => %20s (%s)",
20039          sw_if_from_name, sw_if_to_name, states[mp->state]);
20040 }
20041
20042 static void
20043   vl_api_sw_interface_span_details_t_handler_json
20044   (vl_api_sw_interface_span_details_t * mp)
20045 {
20046   vat_main_t *vam = &vat_main;
20047   vat_json_node_t *node = NULL;
20048   u8 *sw_if_from_name = 0;
20049   u8 *sw_if_to_name = 0;
20050   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20051   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20052   hash_pair_t *p;
20053
20054   /* *INDENT-OFF* */
20055   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20056   ({
20057     if ((u32) p->value[0] == sw_if_index_from)
20058       {
20059         sw_if_from_name = (u8 *)(p->key);
20060         if (sw_if_to_name)
20061           break;
20062       }
20063     if ((u32) p->value[0] == sw_if_index_to)
20064       {
20065         sw_if_to_name = (u8 *)(p->key);
20066         if (sw_if_from_name)
20067           break;
20068       }
20069   }));
20070   /* *INDENT-ON* */
20071
20072   if (VAT_JSON_ARRAY != vam->json_tree.type)
20073     {
20074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20075       vat_json_init_array (&vam->json_tree);
20076     }
20077   node = vat_json_array_add (&vam->json_tree);
20078
20079   vat_json_init_object (node);
20080   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20081   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20082   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20083   if (0 != sw_if_to_name)
20084     {
20085       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20086     }
20087   vat_json_object_add_uint (node, "state", mp->state);
20088 }
20089
20090 static int
20091 api_sw_interface_span_dump (vat_main_t * vam)
20092 {
20093   unformat_input_t *input = vam->input;
20094   vl_api_sw_interface_span_dump_t *mp;
20095   vl_api_control_ping_t *mp_ping;
20096   u8 is_l2 = 0;
20097   int ret;
20098
20099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20100     {
20101       if (unformat (input, "l2"))
20102         is_l2 = 1;
20103       else
20104         break;
20105     }
20106
20107   M (SW_INTERFACE_SPAN_DUMP, mp);
20108   mp->is_l2 = is_l2;
20109   S (mp);
20110
20111   /* Use a control ping for synchronization */
20112   MPING (CONTROL_PING, mp_ping);
20113   S (mp_ping);
20114
20115   W (ret);
20116   return ret;
20117 }
20118
20119 int
20120 api_pg_create_interface (vat_main_t * vam)
20121 {
20122   unformat_input_t *input = vam->input;
20123   vl_api_pg_create_interface_t *mp;
20124
20125   u32 if_id = ~0;
20126   int ret;
20127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20128     {
20129       if (unformat (input, "if_id %d", &if_id))
20130         ;
20131       else
20132         break;
20133     }
20134   if (if_id == ~0)
20135     {
20136       errmsg ("missing pg interface index");
20137       return -99;
20138     }
20139
20140   /* Construct the API message */
20141   M (PG_CREATE_INTERFACE, mp);
20142   mp->context = 0;
20143   mp->interface_id = ntohl (if_id);
20144
20145   S (mp);
20146   W (ret);
20147   return ret;
20148 }
20149
20150 int
20151 api_pg_capture (vat_main_t * vam)
20152 {
20153   unformat_input_t *input = vam->input;
20154   vl_api_pg_capture_t *mp;
20155
20156   u32 if_id = ~0;
20157   u8 enable = 1;
20158   u32 count = 1;
20159   u8 pcap_file_set = 0;
20160   u8 *pcap_file = 0;
20161   int ret;
20162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20163     {
20164       if (unformat (input, "if_id %d", &if_id))
20165         ;
20166       else if (unformat (input, "pcap %s", &pcap_file))
20167         pcap_file_set = 1;
20168       else if (unformat (input, "count %d", &count))
20169         ;
20170       else if (unformat (input, "disable"))
20171         enable = 0;
20172       else
20173         break;
20174     }
20175   if (if_id == ~0)
20176     {
20177       errmsg ("missing pg interface index");
20178       return -99;
20179     }
20180   if (pcap_file_set > 0)
20181     {
20182       if (vec_len (pcap_file) > 255)
20183         {
20184           errmsg ("pcap file name is too long");
20185           return -99;
20186         }
20187     }
20188
20189   u32 name_len = vec_len (pcap_file);
20190   /* Construct the API message */
20191   M (PG_CAPTURE, mp);
20192   mp->context = 0;
20193   mp->interface_id = ntohl (if_id);
20194   mp->is_enabled = enable;
20195   mp->count = ntohl (count);
20196   mp->pcap_name_length = ntohl (name_len);
20197   if (pcap_file_set != 0)
20198     {
20199       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20200     }
20201   vec_free (pcap_file);
20202
20203   S (mp);
20204   W (ret);
20205   return ret;
20206 }
20207
20208 int
20209 api_pg_enable_disable (vat_main_t * vam)
20210 {
20211   unformat_input_t *input = vam->input;
20212   vl_api_pg_enable_disable_t *mp;
20213
20214   u8 enable = 1;
20215   u8 stream_name_set = 0;
20216   u8 *stream_name = 0;
20217   int ret;
20218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20219     {
20220       if (unformat (input, "stream %s", &stream_name))
20221         stream_name_set = 1;
20222       else if (unformat (input, "disable"))
20223         enable = 0;
20224       else
20225         break;
20226     }
20227
20228   if (stream_name_set > 0)
20229     {
20230       if (vec_len (stream_name) > 255)
20231         {
20232           errmsg ("stream name too long");
20233           return -99;
20234         }
20235     }
20236
20237   u32 name_len = vec_len (stream_name);
20238   /* Construct the API message */
20239   M (PG_ENABLE_DISABLE, mp);
20240   mp->context = 0;
20241   mp->is_enabled = enable;
20242   if (stream_name_set != 0)
20243     {
20244       mp->stream_name_length = ntohl (name_len);
20245       clib_memcpy (mp->stream_name, stream_name, name_len);
20246     }
20247   vec_free (stream_name);
20248
20249   S (mp);
20250   W (ret);
20251   return ret;
20252 }
20253
20254 int
20255 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20256 {
20257   unformat_input_t *input = vam->input;
20258   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20259
20260   u16 *low_ports = 0;
20261   u16 *high_ports = 0;
20262   u16 this_low;
20263   u16 this_hi;
20264   ip4_address_t ip4_addr;
20265   ip6_address_t ip6_addr;
20266   u32 length;
20267   u32 tmp, tmp2;
20268   u8 prefix_set = 0;
20269   u32 vrf_id = ~0;
20270   u8 is_add = 1;
20271   u8 is_ipv6 = 0;
20272   int ret;
20273
20274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20275     {
20276       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20277         {
20278           prefix_set = 1;
20279         }
20280       else
20281         if (unformat
20282             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20283         {
20284           prefix_set = 1;
20285           is_ipv6 = 1;
20286         }
20287       else if (unformat (input, "vrf %d", &vrf_id))
20288         ;
20289       else if (unformat (input, "del"))
20290         is_add = 0;
20291       else if (unformat (input, "port %d", &tmp))
20292         {
20293           if (tmp == 0 || tmp > 65535)
20294             {
20295               errmsg ("port %d out of range", tmp);
20296               return -99;
20297             }
20298           this_low = tmp;
20299           this_hi = this_low + 1;
20300           vec_add1 (low_ports, this_low);
20301           vec_add1 (high_ports, this_hi);
20302         }
20303       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20304         {
20305           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20306             {
20307               errmsg ("incorrect range parameters");
20308               return -99;
20309             }
20310           this_low = tmp;
20311           /* Note: in debug CLI +1 is added to high before
20312              passing to real fn that does "the work"
20313              (ip_source_and_port_range_check_add_del).
20314              This fn is a wrapper around the binary API fn a
20315              control plane will call, which expects this increment
20316              to have occurred. Hence letting the binary API control
20317              plane fn do the increment for consistency between VAT
20318              and other control planes.
20319            */
20320           this_hi = tmp2;
20321           vec_add1 (low_ports, this_low);
20322           vec_add1 (high_ports, this_hi);
20323         }
20324       else
20325         break;
20326     }
20327
20328   if (prefix_set == 0)
20329     {
20330       errmsg ("<address>/<mask> not specified");
20331       return -99;
20332     }
20333
20334   if (vrf_id == ~0)
20335     {
20336       errmsg ("VRF ID required, not specified");
20337       return -99;
20338     }
20339
20340   if (vrf_id == 0)
20341     {
20342       errmsg
20343         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20344       return -99;
20345     }
20346
20347   if (vec_len (low_ports) == 0)
20348     {
20349       errmsg ("At least one port or port range required");
20350       return -99;
20351     }
20352
20353   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20354
20355   mp->is_add = is_add;
20356
20357   if (is_ipv6)
20358     {
20359       mp->is_ipv6 = 1;
20360       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20361     }
20362   else
20363     {
20364       mp->is_ipv6 = 0;
20365       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20366     }
20367
20368   mp->mask_length = length;
20369   mp->number_of_ranges = vec_len (low_ports);
20370
20371   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20372   vec_free (low_ports);
20373
20374   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20375   vec_free (high_ports);
20376
20377   mp->vrf_id = ntohl (vrf_id);
20378
20379   S (mp);
20380   W (ret);
20381   return ret;
20382 }
20383
20384 int
20385 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20386 {
20387   unformat_input_t *input = vam->input;
20388   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20389   u32 sw_if_index = ~0;
20390   int vrf_set = 0;
20391   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20392   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20393   u8 is_add = 1;
20394   int ret;
20395
20396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20397     {
20398       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20399         ;
20400       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20401         ;
20402       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20403         vrf_set = 1;
20404       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20405         vrf_set = 1;
20406       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20407         vrf_set = 1;
20408       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20409         vrf_set = 1;
20410       else if (unformat (input, "del"))
20411         is_add = 0;
20412       else
20413         break;
20414     }
20415
20416   if (sw_if_index == ~0)
20417     {
20418       errmsg ("Interface required but not specified");
20419       return -99;
20420     }
20421
20422   if (vrf_set == 0)
20423     {
20424       errmsg ("VRF ID required but not specified");
20425       return -99;
20426     }
20427
20428   if (tcp_out_vrf_id == 0
20429       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20430     {
20431       errmsg
20432         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20433       return -99;
20434     }
20435
20436   /* Construct the API message */
20437   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20438
20439   mp->sw_if_index = ntohl (sw_if_index);
20440   mp->is_add = is_add;
20441   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20442   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20443   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20444   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20445
20446   /* send it... */
20447   S (mp);
20448
20449   /* Wait for a reply... */
20450   W (ret);
20451   return ret;
20452 }
20453
20454 static int
20455 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20456 {
20457   unformat_input_t *i = vam->input;
20458   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20459   u32 local_sa_id = 0;
20460   u32 remote_sa_id = 0;
20461   ip4_address_t src_address;
20462   ip4_address_t dst_address;
20463   u8 is_add = 1;
20464   int ret;
20465
20466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20467     {
20468       if (unformat (i, "local_sa %d", &local_sa_id))
20469         ;
20470       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20471         ;
20472       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20473         ;
20474       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20475         ;
20476       else if (unformat (i, "del"))
20477         is_add = 0;
20478       else
20479         {
20480           clib_warning ("parse error '%U'", format_unformat_error, i);
20481           return -99;
20482         }
20483     }
20484
20485   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20486
20487   mp->local_sa_id = ntohl (local_sa_id);
20488   mp->remote_sa_id = ntohl (remote_sa_id);
20489   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20490   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20491   mp->is_add = is_add;
20492
20493   S (mp);
20494   W (ret);
20495   return ret;
20496 }
20497
20498 static int
20499 api_punt (vat_main_t * vam)
20500 {
20501   unformat_input_t *i = vam->input;
20502   vl_api_punt_t *mp;
20503   u32 ipv = ~0;
20504   u32 protocol = ~0;
20505   u32 port = ~0;
20506   int is_add = 1;
20507   int ret;
20508
20509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20510     {
20511       if (unformat (i, "ip %d", &ipv))
20512         ;
20513       else if (unformat (i, "protocol %d", &protocol))
20514         ;
20515       else if (unformat (i, "port %d", &port))
20516         ;
20517       else if (unformat (i, "del"))
20518         is_add = 0;
20519       else
20520         {
20521           clib_warning ("parse error '%U'", format_unformat_error, i);
20522           return -99;
20523         }
20524     }
20525
20526   M (PUNT, mp);
20527
20528   mp->is_add = (u8) is_add;
20529   mp->ipv = (u8) ipv;
20530   mp->l4_protocol = (u8) protocol;
20531   mp->l4_port = htons ((u16) port);
20532
20533   S (mp);
20534   W (ret);
20535   return ret;
20536 }
20537
20538 static void vl_api_ipsec_gre_tunnel_details_t_handler
20539   (vl_api_ipsec_gre_tunnel_details_t * mp)
20540 {
20541   vat_main_t *vam = &vat_main;
20542
20543   print (vam->ofp, "%11d%15U%15U%14d%14d",
20544          ntohl (mp->sw_if_index),
20545          format_ip4_address, &mp->src_address,
20546          format_ip4_address, &mp->dst_address,
20547          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20548 }
20549
20550 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20551   (vl_api_ipsec_gre_tunnel_details_t * mp)
20552 {
20553   vat_main_t *vam = &vat_main;
20554   vat_json_node_t *node = NULL;
20555   struct in_addr ip4;
20556
20557   if (VAT_JSON_ARRAY != vam->json_tree.type)
20558     {
20559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20560       vat_json_init_array (&vam->json_tree);
20561     }
20562   node = vat_json_array_add (&vam->json_tree);
20563
20564   vat_json_init_object (node);
20565   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20566   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20567   vat_json_object_add_ip4 (node, "src_address", ip4);
20568   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20569   vat_json_object_add_ip4 (node, "dst_address", ip4);
20570   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20571   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20572 }
20573
20574 static int
20575 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20576 {
20577   unformat_input_t *i = vam->input;
20578   vl_api_ipsec_gre_tunnel_dump_t *mp;
20579   vl_api_control_ping_t *mp_ping;
20580   u32 sw_if_index;
20581   u8 sw_if_index_set = 0;
20582   int ret;
20583
20584   /* Parse args required to build the message */
20585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20586     {
20587       if (unformat (i, "sw_if_index %d", &sw_if_index))
20588         sw_if_index_set = 1;
20589       else
20590         break;
20591     }
20592
20593   if (sw_if_index_set == 0)
20594     {
20595       sw_if_index = ~0;
20596     }
20597
20598   if (!vam->json_output)
20599     {
20600       print (vam->ofp, "%11s%15s%15s%14s%14s",
20601              "sw_if_index", "src_address", "dst_address",
20602              "local_sa_id", "remote_sa_id");
20603     }
20604
20605   /* Get list of gre-tunnel interfaces */
20606   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20607
20608   mp->sw_if_index = htonl (sw_if_index);
20609
20610   S (mp);
20611
20612   /* Use a control ping for synchronization */
20613   MPING (CONTROL_PING, mp_ping);
20614   S (mp_ping);
20615
20616   W (ret);
20617   return ret;
20618 }
20619
20620 static int
20621 api_delete_subif (vat_main_t * vam)
20622 {
20623   unformat_input_t *i = vam->input;
20624   vl_api_delete_subif_t *mp;
20625   u32 sw_if_index = ~0;
20626   int ret;
20627
20628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20629     {
20630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20631         ;
20632       if (unformat (i, "sw_if_index %d", &sw_if_index))
20633         ;
20634       else
20635         break;
20636     }
20637
20638   if (sw_if_index == ~0)
20639     {
20640       errmsg ("missing sw_if_index");
20641       return -99;
20642     }
20643
20644   /* Construct the API message */
20645   M (DELETE_SUBIF, mp);
20646   mp->sw_if_index = ntohl (sw_if_index);
20647
20648   S (mp);
20649   W (ret);
20650   return ret;
20651 }
20652
20653 #define foreach_pbb_vtr_op      \
20654 _("disable",  L2_VTR_DISABLED)  \
20655 _("pop",  L2_VTR_POP_2)         \
20656 _("push",  L2_VTR_PUSH_2)
20657
20658 static int
20659 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20660 {
20661   unformat_input_t *i = vam->input;
20662   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20663   u32 sw_if_index = ~0, vtr_op = ~0;
20664   u16 outer_tag = ~0;
20665   u8 dmac[6], smac[6];
20666   u8 dmac_set = 0, smac_set = 0;
20667   u16 vlanid = 0;
20668   u32 sid = ~0;
20669   u32 tmp;
20670   int ret;
20671
20672   /* Shut up coverity */
20673   memset (dmac, 0, sizeof (dmac));
20674   memset (smac, 0, sizeof (smac));
20675
20676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20677     {
20678       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20679         ;
20680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20681         ;
20682       else if (unformat (i, "vtr_op %d", &vtr_op))
20683         ;
20684 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20685       foreach_pbb_vtr_op
20686 #undef _
20687         else if (unformat (i, "translate_pbb_stag"))
20688         {
20689           if (unformat (i, "%d", &tmp))
20690             {
20691               vtr_op = L2_VTR_TRANSLATE_2_1;
20692               outer_tag = tmp;
20693             }
20694           else
20695             {
20696               errmsg
20697                 ("translate_pbb_stag operation requires outer tag definition");
20698               return -99;
20699             }
20700         }
20701       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20702         dmac_set++;
20703       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20704         smac_set++;
20705       else if (unformat (i, "sid %d", &sid))
20706         ;
20707       else if (unformat (i, "vlanid %d", &tmp))
20708         vlanid = tmp;
20709       else
20710         {
20711           clib_warning ("parse error '%U'", format_unformat_error, i);
20712           return -99;
20713         }
20714     }
20715
20716   if ((sw_if_index == ~0) || (vtr_op == ~0))
20717     {
20718       errmsg ("missing sw_if_index or vtr operation");
20719       return -99;
20720     }
20721   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20722       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20723     {
20724       errmsg
20725         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20726       return -99;
20727     }
20728
20729   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20730   mp->sw_if_index = ntohl (sw_if_index);
20731   mp->vtr_op = ntohl (vtr_op);
20732   mp->outer_tag = ntohs (outer_tag);
20733   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20734   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20735   mp->b_vlanid = ntohs (vlanid);
20736   mp->i_sid = ntohl (sid);
20737
20738   S (mp);
20739   W (ret);
20740   return ret;
20741 }
20742
20743 static int
20744 api_flow_classify_set_interface (vat_main_t * vam)
20745 {
20746   unformat_input_t *i = vam->input;
20747   vl_api_flow_classify_set_interface_t *mp;
20748   u32 sw_if_index;
20749   int sw_if_index_set;
20750   u32 ip4_table_index = ~0;
20751   u32 ip6_table_index = ~0;
20752   u8 is_add = 1;
20753   int ret;
20754
20755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20756     {
20757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20758         sw_if_index_set = 1;
20759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20760         sw_if_index_set = 1;
20761       else if (unformat (i, "del"))
20762         is_add = 0;
20763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20764         ;
20765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20766         ;
20767       else
20768         {
20769           clib_warning ("parse error '%U'", format_unformat_error, i);
20770           return -99;
20771         }
20772     }
20773
20774   if (sw_if_index_set == 0)
20775     {
20776       errmsg ("missing interface name or sw_if_index");
20777       return -99;
20778     }
20779
20780   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20781
20782   mp->sw_if_index = ntohl (sw_if_index);
20783   mp->ip4_table_index = ntohl (ip4_table_index);
20784   mp->ip6_table_index = ntohl (ip6_table_index);
20785   mp->is_add = is_add;
20786
20787   S (mp);
20788   W (ret);
20789   return ret;
20790 }
20791
20792 static int
20793 api_flow_classify_dump (vat_main_t * vam)
20794 {
20795   unformat_input_t *i = vam->input;
20796   vl_api_flow_classify_dump_t *mp;
20797   vl_api_control_ping_t *mp_ping;
20798   u8 type = FLOW_CLASSIFY_N_TABLES;
20799   int ret;
20800
20801   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20802     ;
20803   else
20804     {
20805       errmsg ("classify table type must be specified");
20806       return -99;
20807     }
20808
20809   if (!vam->json_output)
20810     {
20811       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20812     }
20813
20814   M (FLOW_CLASSIFY_DUMP, mp);
20815   mp->type = type;
20816   /* send it... */
20817   S (mp);
20818
20819   /* Use a control ping for synchronization */
20820   MPING (CONTROL_PING, mp_ping);
20821   S (mp_ping);
20822
20823   /* Wait for a reply... */
20824   W (ret);
20825   return ret;
20826 }
20827
20828 static int
20829 api_feature_enable_disable (vat_main_t * vam)
20830 {
20831   unformat_input_t *i = vam->input;
20832   vl_api_feature_enable_disable_t *mp;
20833   u8 *arc_name = 0;
20834   u8 *feature_name = 0;
20835   u32 sw_if_index = ~0;
20836   u8 enable = 1;
20837   int ret;
20838
20839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20840     {
20841       if (unformat (i, "arc_name %s", &arc_name))
20842         ;
20843       else if (unformat (i, "feature_name %s", &feature_name))
20844         ;
20845       else
20846         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20847         ;
20848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20849         ;
20850       else if (unformat (i, "disable"))
20851         enable = 0;
20852       else
20853         break;
20854     }
20855
20856   if (arc_name == 0)
20857     {
20858       errmsg ("missing arc name");
20859       return -99;
20860     }
20861   if (vec_len (arc_name) > 63)
20862     {
20863       errmsg ("arc name too long");
20864     }
20865
20866   if (feature_name == 0)
20867     {
20868       errmsg ("missing feature name");
20869       return -99;
20870     }
20871   if (vec_len (feature_name) > 63)
20872     {
20873       errmsg ("feature name too long");
20874     }
20875
20876   if (sw_if_index == ~0)
20877     {
20878       errmsg ("missing interface name or sw_if_index");
20879       return -99;
20880     }
20881
20882   /* Construct the API message */
20883   M (FEATURE_ENABLE_DISABLE, mp);
20884   mp->sw_if_index = ntohl (sw_if_index);
20885   mp->enable = enable;
20886   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20887   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20888   vec_free (arc_name);
20889   vec_free (feature_name);
20890
20891   S (mp);
20892   W (ret);
20893   return ret;
20894 }
20895
20896 static int
20897 api_sw_interface_tag_add_del (vat_main_t * vam)
20898 {
20899   unformat_input_t *i = vam->input;
20900   vl_api_sw_interface_tag_add_del_t *mp;
20901   u32 sw_if_index = ~0;
20902   u8 *tag = 0;
20903   u8 enable = 1;
20904   int ret;
20905
20906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20907     {
20908       if (unformat (i, "tag %s", &tag))
20909         ;
20910       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20911         ;
20912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20913         ;
20914       else if (unformat (i, "del"))
20915         enable = 0;
20916       else
20917         break;
20918     }
20919
20920   if (sw_if_index == ~0)
20921     {
20922       errmsg ("missing interface name or sw_if_index");
20923       return -99;
20924     }
20925
20926   if (enable && (tag == 0))
20927     {
20928       errmsg ("no tag specified");
20929       return -99;
20930     }
20931
20932   /* Construct the API message */
20933   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20934   mp->sw_if_index = ntohl (sw_if_index);
20935   mp->is_add = enable;
20936   if (enable)
20937     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20938   vec_free (tag);
20939
20940   S (mp);
20941   W (ret);
20942   return ret;
20943 }
20944
20945 static void vl_api_l2_xconnect_details_t_handler
20946   (vl_api_l2_xconnect_details_t * mp)
20947 {
20948   vat_main_t *vam = &vat_main;
20949
20950   print (vam->ofp, "%15d%15d",
20951          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20952 }
20953
20954 static void vl_api_l2_xconnect_details_t_handler_json
20955   (vl_api_l2_xconnect_details_t * mp)
20956 {
20957   vat_main_t *vam = &vat_main;
20958   vat_json_node_t *node = NULL;
20959
20960   if (VAT_JSON_ARRAY != vam->json_tree.type)
20961     {
20962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20963       vat_json_init_array (&vam->json_tree);
20964     }
20965   node = vat_json_array_add (&vam->json_tree);
20966
20967   vat_json_init_object (node);
20968   vat_json_object_add_uint (node, "rx_sw_if_index",
20969                             ntohl (mp->rx_sw_if_index));
20970   vat_json_object_add_uint (node, "tx_sw_if_index",
20971                             ntohl (mp->tx_sw_if_index));
20972 }
20973
20974 static int
20975 api_l2_xconnect_dump (vat_main_t * vam)
20976 {
20977   vl_api_l2_xconnect_dump_t *mp;
20978   vl_api_control_ping_t *mp_ping;
20979   int ret;
20980
20981   if (!vam->json_output)
20982     {
20983       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20984     }
20985
20986   M (L2_XCONNECT_DUMP, mp);
20987
20988   S (mp);
20989
20990   /* Use a control ping for synchronization */
20991   MPING (CONTROL_PING, mp_ping);
20992   S (mp_ping);
20993
20994   W (ret);
20995   return ret;
20996 }
20997
20998 static int
20999 api_sw_interface_set_mtu (vat_main_t * vam)
21000 {
21001   unformat_input_t *i = vam->input;
21002   vl_api_sw_interface_set_mtu_t *mp;
21003   u32 sw_if_index = ~0;
21004   u32 mtu = 0;
21005   int ret;
21006
21007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21008     {
21009       if (unformat (i, "mtu %d", &mtu))
21010         ;
21011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21012         ;
21013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21014         ;
21015       else
21016         break;
21017     }
21018
21019   if (sw_if_index == ~0)
21020     {
21021       errmsg ("missing interface name or sw_if_index");
21022       return -99;
21023     }
21024
21025   if (mtu == 0)
21026     {
21027       errmsg ("no mtu specified");
21028       return -99;
21029     }
21030
21031   /* Construct the API message */
21032   M (SW_INTERFACE_SET_MTU, mp);
21033   mp->sw_if_index = ntohl (sw_if_index);
21034   mp->mtu = ntohs ((u16) mtu);
21035
21036   S (mp);
21037   W (ret);
21038   return ret;
21039 }
21040
21041 static int
21042 api_p2p_ethernet_add (vat_main_t * vam)
21043 {
21044   unformat_input_t *i = vam->input;
21045   vl_api_p2p_ethernet_add_t *mp;
21046   u32 parent_if_index = ~0;
21047   u32 sub_id = ~0;
21048   u8 remote_mac[6];
21049   u8 mac_set = 0;
21050   int ret;
21051
21052   memset (remote_mac, 0, sizeof (remote_mac));
21053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21054     {
21055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21056         ;
21057       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21058         ;
21059       else
21060         if (unformat
21061             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21062         mac_set++;
21063       else if (unformat (i, "sub_id %d", &sub_id))
21064         ;
21065       else
21066         {
21067           clib_warning ("parse error '%U'", format_unformat_error, i);
21068           return -99;
21069         }
21070     }
21071
21072   if (parent_if_index == ~0)
21073     {
21074       errmsg ("missing interface name or sw_if_index");
21075       return -99;
21076     }
21077   if (mac_set == 0)
21078     {
21079       errmsg ("missing remote mac address");
21080       return -99;
21081     }
21082   if (sub_id == ~0)
21083     {
21084       errmsg ("missing sub-interface id");
21085       return -99;
21086     }
21087
21088   M (P2P_ETHERNET_ADD, mp);
21089   mp->parent_if_index = ntohl (parent_if_index);
21090   mp->subif_id = ntohl (sub_id);
21091   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21092
21093   S (mp);
21094   W (ret);
21095   return ret;
21096 }
21097
21098 static int
21099 api_p2p_ethernet_del (vat_main_t * vam)
21100 {
21101   unformat_input_t *i = vam->input;
21102   vl_api_p2p_ethernet_del_t *mp;
21103   u32 parent_if_index = ~0;
21104   u8 remote_mac[6];
21105   u8 mac_set = 0;
21106   int ret;
21107
21108   memset (remote_mac, 0, sizeof (remote_mac));
21109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21110     {
21111       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21112         ;
21113       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21114         ;
21115       else
21116         if (unformat
21117             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21118         mac_set++;
21119       else
21120         {
21121           clib_warning ("parse error '%U'", format_unformat_error, i);
21122           return -99;
21123         }
21124     }
21125
21126   if (parent_if_index == ~0)
21127     {
21128       errmsg ("missing interface name or sw_if_index");
21129       return -99;
21130     }
21131   if (mac_set == 0)
21132     {
21133       errmsg ("missing remote mac address");
21134       return -99;
21135     }
21136
21137   M (P2P_ETHERNET_DEL, mp);
21138   mp->parent_if_index = ntohl (parent_if_index);
21139   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21140
21141   S (mp);
21142   W (ret);
21143   return ret;
21144 }
21145
21146 static int
21147 api_lldp_config (vat_main_t * vam)
21148 {
21149   unformat_input_t *i = vam->input;
21150   vl_api_lldp_config_t *mp;
21151   int tx_hold = 0;
21152   int tx_interval = 0;
21153   u8 *sys_name = NULL;
21154   int ret;
21155
21156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21157     {
21158       if (unformat (i, "system-name %s", &sys_name))
21159         ;
21160       else if (unformat (i, "tx-hold %d", &tx_hold))
21161         ;
21162       else if (unformat (i, "tx-interval %d", &tx_interval))
21163         ;
21164       else
21165         {
21166           clib_warning ("parse error '%U'", format_unformat_error, i);
21167           return -99;
21168         }
21169     }
21170
21171   vec_add1 (sys_name, 0);
21172
21173   M (LLDP_CONFIG, mp);
21174   mp->tx_hold = htonl (tx_hold);
21175   mp->tx_interval = htonl (tx_interval);
21176   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21177   vec_free (sys_name);
21178
21179   S (mp);
21180   W (ret);
21181   return ret;
21182 }
21183
21184 static int
21185 api_sw_interface_set_lldp (vat_main_t * vam)
21186 {
21187   unformat_input_t *i = vam->input;
21188   vl_api_sw_interface_set_lldp_t *mp;
21189   u32 sw_if_index = ~0;
21190   u32 enable = 1;
21191   u8 *port_desc = NULL, *mgmt_oid = NULL;
21192   ip4_address_t ip4_addr;
21193   ip6_address_t ip6_addr;
21194   int ret;
21195
21196   memset (&ip4_addr, 0, sizeof (ip4_addr));
21197   memset (&ip6_addr, 0, sizeof (ip6_addr));
21198
21199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21200     {
21201       if (unformat (i, "disable"))
21202         enable = 0;
21203       else
21204         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21205         ;
21206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21207         ;
21208       else if (unformat (i, "port-desc %s", &port_desc))
21209         ;
21210       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21211         ;
21212       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21213         ;
21214       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21215         ;
21216       else
21217         break;
21218     }
21219
21220   if (sw_if_index == ~0)
21221     {
21222       errmsg ("missing interface name or sw_if_index");
21223       return -99;
21224     }
21225
21226   /* Construct the API message */
21227   vec_add1 (port_desc, 0);
21228   vec_add1 (mgmt_oid, 0);
21229   M (SW_INTERFACE_SET_LLDP, mp);
21230   mp->sw_if_index = ntohl (sw_if_index);
21231   mp->enable = enable;
21232   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21233   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21234   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21235   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21236   vec_free (port_desc);
21237   vec_free (mgmt_oid);
21238
21239   S (mp);
21240   W (ret);
21241   return ret;
21242 }
21243
21244 static int
21245 api_tcp_configure_src_addresses (vat_main_t * vam)
21246 {
21247   vl_api_tcp_configure_src_addresses_t *mp;
21248   unformat_input_t *i = vam->input;
21249   ip4_address_t v4first, v4last;
21250   ip6_address_t v6first, v6last;
21251   u8 range_set = 0;
21252   u32 vrf_id = 0;
21253   int ret;
21254
21255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21256     {
21257       if (unformat (i, "%U - %U",
21258                     unformat_ip4_address, &v4first,
21259                     unformat_ip4_address, &v4last))
21260         {
21261           if (range_set)
21262             {
21263               errmsg ("one range per message (range already set)");
21264               return -99;
21265             }
21266           range_set = 1;
21267         }
21268       else if (unformat (i, "%U - %U",
21269                          unformat_ip6_address, &v6first,
21270                          unformat_ip6_address, &v6last))
21271         {
21272           if (range_set)
21273             {
21274               errmsg ("one range per message (range already set)");
21275               return -99;
21276             }
21277           range_set = 2;
21278         }
21279       else if (unformat (i, "vrf %d", &vrf_id))
21280         ;
21281       else
21282         break;
21283     }
21284
21285   if (range_set == 0)
21286     {
21287       errmsg ("address range not set");
21288       return -99;
21289     }
21290
21291   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21292   mp->vrf_id = ntohl (vrf_id);
21293   /* ipv6? */
21294   if (range_set == 2)
21295     {
21296       mp->is_ipv6 = 1;
21297       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21298       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21299     }
21300   else
21301     {
21302       mp->is_ipv6 = 0;
21303       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21304       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21305     }
21306   S (mp);
21307   W (ret);
21308   return ret;
21309 }
21310
21311 static int
21312 api_app_namespace_add_del (vat_main_t * vam)
21313 {
21314   vl_api_app_namespace_add_del_t *mp;
21315   unformat_input_t *i = vam->input;
21316   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21317   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21318   u64 secret;
21319   int ret;
21320
21321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21322     {
21323       if (unformat (i, "id %_%v%_", &ns_id))
21324         ;
21325       else if (unformat (i, "secret %lu", &secret))
21326         secret_set = 1;
21327       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21328         sw_if_index_set = 1;
21329       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21330         ;
21331       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21332         ;
21333       else
21334         break;
21335     }
21336   if (!ns_id || !secret_set || !sw_if_index_set)
21337     {
21338       errmsg ("namespace id, secret and sw_if_index must be set");
21339       return -99;
21340     }
21341   if (vec_len (ns_id) > 64)
21342     {
21343       errmsg ("namespace id too long");
21344       return -99;
21345     }
21346   M (APP_NAMESPACE_ADD_DEL, mp);
21347
21348   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21349   mp->namespace_id_len = vec_len (ns_id);
21350   mp->secret = clib_host_to_net_u64 (secret);
21351   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21352   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21353   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21354   vec_free (ns_id);
21355   S (mp);
21356   W (ret);
21357   return ret;
21358 }
21359
21360 static int
21361 api_memfd_segment_create (vat_main_t * vam)
21362 {
21363 #if VPP_API_TEST_BUILTIN == 0
21364   unformat_input_t *i = vam->input;
21365   vl_api_memfd_segment_create_t *mp;
21366   u64 size = 64 << 20;
21367   int ret;
21368
21369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21370     {
21371       if (unformat (i, "size %U", unformat_memory_size, &size))
21372         ;
21373       else
21374         break;
21375     }
21376
21377   M (MEMFD_SEGMENT_CREATE, mp);
21378   mp->requested_size = size;
21379   S (mp);
21380   W (ret);
21381   return ret;
21382
21383 #else
21384   errmsg ("memfd_segment_create (builtin) not supported");
21385   return -99;
21386 #endif
21387 }
21388
21389 static int
21390 api_dns_enable_disable (vat_main_t * vam)
21391 {
21392   unformat_input_t *line_input = vam->input;
21393   vl_api_dns_enable_disable_t *mp;
21394   u8 enable_disable = 1;
21395   int ret;
21396
21397   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21398     {
21399       if (unformat (line_input, "disable"))
21400         enable_disable = 0;
21401       if (unformat (line_input, "enable"))
21402         enable_disable = 1;
21403       else
21404         break;
21405     }
21406
21407   /* Construct the API message */
21408   M (DNS_ENABLE_DISABLE, mp);
21409   mp->enable = enable_disable;
21410
21411   /* send it... */
21412   S (mp);
21413   /* Wait for the reply */
21414   W (ret);
21415   return ret;
21416 }
21417
21418 static int
21419 api_dns_resolve_name (vat_main_t * vam)
21420 {
21421   unformat_input_t *line_input = vam->input;
21422   vl_api_dns_resolve_name_t *mp;
21423   u8 *name = 0;
21424   int ret;
21425
21426   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21427     {
21428       if (unformat (line_input, "%s", &name))
21429         ;
21430       else
21431         break;
21432     }
21433
21434   if (vec_len (name) > 127)
21435     {
21436       errmsg ("name too long");
21437       return -99;
21438     }
21439
21440   /* Construct the API message */
21441   M (DNS_RESOLVE_NAME, mp);
21442   memcpy (mp->name, name, vec_len (name));
21443   vec_free (name);
21444
21445   /* send it... */
21446   S (mp);
21447   /* Wait for the reply */
21448   W (ret);
21449   return ret;
21450 }
21451
21452 static int
21453 api_dns_resolve_ip (vat_main_t * vam)
21454 {
21455   unformat_input_t *line_input = vam->input;
21456   vl_api_dns_resolve_ip_t *mp;
21457   int is_ip6 = -1;
21458   ip4_address_t addr4;
21459   ip6_address_t addr6;
21460   int ret;
21461
21462   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21463     {
21464       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21465         is_ip6 = 1;
21466       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21467         is_ip6 = 0;
21468       else
21469         break;
21470     }
21471
21472   if (is_ip6 == -1)
21473     {
21474       errmsg ("missing address");
21475       return -99;
21476     }
21477
21478   /* Construct the API message */
21479   M (DNS_RESOLVE_IP, mp);
21480   mp->is_ip6 = is_ip6;
21481   if (is_ip6)
21482     memcpy (mp->address, &addr6, sizeof (addr6));
21483   else
21484     memcpy (mp->address, &addr4, sizeof (addr4));
21485
21486   /* send it... */
21487   S (mp);
21488   /* Wait for the reply */
21489   W (ret);
21490   return ret;
21491 }
21492
21493 static int
21494 api_dns_name_server_add_del (vat_main_t * vam)
21495 {
21496   unformat_input_t *i = vam->input;
21497   vl_api_dns_name_server_add_del_t *mp;
21498   u8 is_add = 1;
21499   ip6_address_t ip6_server;
21500   ip4_address_t ip4_server;
21501   int ip6_set = 0;
21502   int ip4_set = 0;
21503   int ret = 0;
21504
21505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21506     {
21507       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21508         ip6_set = 1;
21509       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21510         ip4_set = 1;
21511       else if (unformat (i, "del"))
21512         is_add = 0;
21513       else
21514         {
21515           clib_warning ("parse error '%U'", format_unformat_error, i);
21516           return -99;
21517         }
21518     }
21519
21520   if (ip4_set && ip6_set)
21521     {
21522       errmsg ("Only one server address allowed per message");
21523       return -99;
21524     }
21525   if ((ip4_set + ip6_set) == 0)
21526     {
21527       errmsg ("Server address required");
21528       return -99;
21529     }
21530
21531   /* Construct the API message */
21532   M (DNS_NAME_SERVER_ADD_DEL, mp);
21533
21534   if (ip6_set)
21535     {
21536       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21537       mp->is_ip6 = 1;
21538     }
21539   else
21540     {
21541       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21542       mp->is_ip6 = 0;
21543     }
21544
21545   mp->is_add = is_add;
21546
21547   /* send it... */
21548   S (mp);
21549
21550   /* Wait for a reply, return good/bad news  */
21551   W (ret);
21552   return ret;
21553 }
21554
21555 static int
21556 api_session_rule_add_del (vat_main_t * vam)
21557 {
21558   vl_api_session_rule_add_del_t *mp;
21559   unformat_input_t *i = vam->input;
21560   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21561   u32 appns_index = 0, scope = 0;
21562   ip4_address_t lcl_ip4, rmt_ip4;
21563   ip6_address_t lcl_ip6, rmt_ip6;
21564   u8 is_ip4 = 1, conn_set = 0;
21565   u8 is_add = 1;
21566   int ret;
21567
21568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21569     {
21570       if (unformat (i, "del"))
21571         is_add = 0;
21572       else if (unformat (i, "add"))
21573         ;
21574       else if (unformat (i, "proto tcp"))
21575         proto = 0;
21576       else if (unformat (i, "proto udp"))
21577         proto = 1;
21578       else if (unformat (i, "appns %d", &appns_index))
21579         ;
21580       else if (unformat (i, "scope %d", &scope))
21581         ;
21582       else
21583         if (unformat
21584             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21585              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21586              &rmt_port))
21587         {
21588           is_ip4 = 1;
21589           conn_set = 1;
21590         }
21591       else
21592         if (unformat
21593             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21594              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21595              &rmt_port))
21596         {
21597           is_ip4 = 0;
21598           conn_set = 1;
21599         }
21600       else if (unformat (i, "action %d", &action))
21601         ;
21602       else
21603         break;
21604     }
21605   if (proto == ~0 || !conn_set || action == ~0)
21606     {
21607       errmsg ("transport proto, connection and action must be set");
21608       return -99;
21609     }
21610
21611   if (scope > 3)
21612     {
21613       errmsg ("scope should be 0-3");
21614       return -99;
21615     }
21616
21617   M (SESSION_RULE_ADD_DEL, mp);
21618
21619   mp->is_ip4 = is_ip4;
21620   mp->transport_proto = proto;
21621   mp->lcl_plen = clib_host_to_net_u16 (lcl_plen);
21622   mp->rmt_plen = clib_host_to_net_u16 (rmt_plen);
21623   mp->action_index = clib_host_to_net_u32 (action);
21624   mp->appns_index = clib_host_to_net_u32 (appns_index);
21625   mp->scope = scope;
21626   mp->is_add = is_add;
21627   if (is_ip4)
21628     {
21629       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21630       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21631     }
21632   else
21633     {
21634       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21635       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21636     }
21637
21638   S (mp);
21639   W (ret);
21640   return ret;
21641 }
21642
21643 static int
21644 q_or_quit (vat_main_t * vam)
21645 {
21646 #if VPP_API_TEST_BUILTIN == 0
21647   longjmp (vam->jump_buf, 1);
21648 #endif
21649   return 0;                     /* not so much */
21650 }
21651
21652 static int
21653 q (vat_main_t * vam)
21654 {
21655   return q_or_quit (vam);
21656 }
21657
21658 static int
21659 quit (vat_main_t * vam)
21660 {
21661   return q_or_quit (vam);
21662 }
21663
21664 static int
21665 comment (vat_main_t * vam)
21666 {
21667   return 0;
21668 }
21669
21670 static int
21671 cmd_cmp (void *a1, void *a2)
21672 {
21673   u8 **c1 = a1;
21674   u8 **c2 = a2;
21675
21676   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21677 }
21678
21679 static int
21680 help (vat_main_t * vam)
21681 {
21682   u8 **cmds = 0;
21683   u8 *name = 0;
21684   hash_pair_t *p;
21685   unformat_input_t *i = vam->input;
21686   int j;
21687
21688   if (unformat (i, "%s", &name))
21689     {
21690       uword *hs;
21691
21692       vec_add1 (name, 0);
21693
21694       hs = hash_get_mem (vam->help_by_name, name);
21695       if (hs)
21696         print (vam->ofp, "usage: %s %s", name, hs[0]);
21697       else
21698         print (vam->ofp, "No such msg / command '%s'", name);
21699       vec_free (name);
21700       return 0;
21701     }
21702
21703   print (vam->ofp, "Help is available for the following:");
21704
21705     /* *INDENT-OFF* */
21706     hash_foreach_pair (p, vam->function_by_name,
21707     ({
21708       vec_add1 (cmds, (u8 *)(p->key));
21709     }));
21710     /* *INDENT-ON* */
21711
21712   vec_sort_with_function (cmds, cmd_cmp);
21713
21714   for (j = 0; j < vec_len (cmds); j++)
21715     print (vam->ofp, "%s", cmds[j]);
21716
21717   vec_free (cmds);
21718   return 0;
21719 }
21720
21721 static int
21722 set (vat_main_t * vam)
21723 {
21724   u8 *name = 0, *value = 0;
21725   unformat_input_t *i = vam->input;
21726
21727   if (unformat (i, "%s", &name))
21728     {
21729       /* The input buffer is a vector, not a string. */
21730       value = vec_dup (i->buffer);
21731       vec_delete (value, i->index, 0);
21732       /* Almost certainly has a trailing newline */
21733       if (value[vec_len (value) - 1] == '\n')
21734         value[vec_len (value) - 1] = 0;
21735       /* Make sure it's a proper string, one way or the other */
21736       vec_add1 (value, 0);
21737       (void) clib_macro_set_value (&vam->macro_main,
21738                                    (char *) name, (char *) value);
21739     }
21740   else
21741     errmsg ("usage: set <name> <value>");
21742
21743   vec_free (name);
21744   vec_free (value);
21745   return 0;
21746 }
21747
21748 static int
21749 unset (vat_main_t * vam)
21750 {
21751   u8 *name = 0;
21752
21753   if (unformat (vam->input, "%s", &name))
21754     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21755       errmsg ("unset: %s wasn't set", name);
21756   vec_free (name);
21757   return 0;
21758 }
21759
21760 typedef struct
21761 {
21762   u8 *name;
21763   u8 *value;
21764 } macro_sort_t;
21765
21766
21767 static int
21768 macro_sort_cmp (void *a1, void *a2)
21769 {
21770   macro_sort_t *s1 = a1;
21771   macro_sort_t *s2 = a2;
21772
21773   return strcmp ((char *) (s1->name), (char *) (s2->name));
21774 }
21775
21776 static int
21777 dump_macro_table (vat_main_t * vam)
21778 {
21779   macro_sort_t *sort_me = 0, *sm;
21780   int i;
21781   hash_pair_t *p;
21782
21783     /* *INDENT-OFF* */
21784     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21785     ({
21786       vec_add2 (sort_me, sm, 1);
21787       sm->name = (u8 *)(p->key);
21788       sm->value = (u8 *) (p->value[0]);
21789     }));
21790     /* *INDENT-ON* */
21791
21792   vec_sort_with_function (sort_me, macro_sort_cmp);
21793
21794   if (vec_len (sort_me))
21795     print (vam->ofp, "%-15s%s", "Name", "Value");
21796   else
21797     print (vam->ofp, "The macro table is empty...");
21798
21799   for (i = 0; i < vec_len (sort_me); i++)
21800     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21801   return 0;
21802 }
21803
21804 static int
21805 dump_node_table (vat_main_t * vam)
21806 {
21807   int i, j;
21808   vlib_node_t *node, *next_node;
21809
21810   if (vec_len (vam->graph_nodes) == 0)
21811     {
21812       print (vam->ofp, "Node table empty, issue get_node_graph...");
21813       return 0;
21814     }
21815
21816   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21817     {
21818       node = vam->graph_nodes[i];
21819       print (vam->ofp, "[%d] %s", i, node->name);
21820       for (j = 0; j < vec_len (node->next_nodes); j++)
21821         {
21822           if (node->next_nodes[j] != ~0)
21823             {
21824               next_node = vam->graph_nodes[node->next_nodes[j]];
21825               print (vam->ofp, "  [%d] %s", j, next_node->name);
21826             }
21827         }
21828     }
21829   return 0;
21830 }
21831
21832 static int
21833 value_sort_cmp (void *a1, void *a2)
21834 {
21835   name_sort_t *n1 = a1;
21836   name_sort_t *n2 = a2;
21837
21838   if (n1->value < n2->value)
21839     return -1;
21840   if (n1->value > n2->value)
21841     return 1;
21842   return 0;
21843 }
21844
21845
21846 static int
21847 dump_msg_api_table (vat_main_t * vam)
21848 {
21849   api_main_t *am = &api_main;
21850   name_sort_t *nses = 0, *ns;
21851   hash_pair_t *hp;
21852   int i;
21853
21854   /* *INDENT-OFF* */
21855   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21856   ({
21857     vec_add2 (nses, ns, 1);
21858     ns->name = (u8 *)(hp->key);
21859     ns->value = (u32) hp->value[0];
21860   }));
21861   /* *INDENT-ON* */
21862
21863   vec_sort_with_function (nses, value_sort_cmp);
21864
21865   for (i = 0; i < vec_len (nses); i++)
21866     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21867   vec_free (nses);
21868   return 0;
21869 }
21870
21871 static int
21872 get_msg_id (vat_main_t * vam)
21873 {
21874   u8 *name_and_crc;
21875   u32 message_index;
21876
21877   if (unformat (vam->input, "%s", &name_and_crc))
21878     {
21879       message_index = vl_api_get_msg_index (name_and_crc);
21880       if (message_index == ~0)
21881         {
21882           print (vam->ofp, " '%s' not found", name_and_crc);
21883           return 0;
21884         }
21885       print (vam->ofp, " '%s' has message index %d",
21886              name_and_crc, message_index);
21887       return 0;
21888     }
21889   errmsg ("name_and_crc required...");
21890   return 0;
21891 }
21892
21893 static int
21894 search_node_table (vat_main_t * vam)
21895 {
21896   unformat_input_t *line_input = vam->input;
21897   u8 *node_to_find;
21898   int j;
21899   vlib_node_t *node, *next_node;
21900   uword *p;
21901
21902   if (vam->graph_node_index_by_name == 0)
21903     {
21904       print (vam->ofp, "Node table empty, issue get_node_graph...");
21905       return 0;
21906     }
21907
21908   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21909     {
21910       if (unformat (line_input, "%s", &node_to_find))
21911         {
21912           vec_add1 (node_to_find, 0);
21913           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21914           if (p == 0)
21915             {
21916               print (vam->ofp, "%s not found...", node_to_find);
21917               goto out;
21918             }
21919           node = vam->graph_nodes[p[0]];
21920           print (vam->ofp, "[%d] %s", p[0], node->name);
21921           for (j = 0; j < vec_len (node->next_nodes); j++)
21922             {
21923               if (node->next_nodes[j] != ~0)
21924                 {
21925                   next_node = vam->graph_nodes[node->next_nodes[j]];
21926                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21927                 }
21928             }
21929         }
21930
21931       else
21932         {
21933           clib_warning ("parse error '%U'", format_unformat_error,
21934                         line_input);
21935           return -99;
21936         }
21937
21938     out:
21939       vec_free (node_to_find);
21940
21941     }
21942
21943   return 0;
21944 }
21945
21946
21947 static int
21948 script (vat_main_t * vam)
21949 {
21950 #if (VPP_API_TEST_BUILTIN==0)
21951   u8 *s = 0;
21952   char *save_current_file;
21953   unformat_input_t save_input;
21954   jmp_buf save_jump_buf;
21955   u32 save_line_number;
21956
21957   FILE *new_fp, *save_ifp;
21958
21959   if (unformat (vam->input, "%s", &s))
21960     {
21961       new_fp = fopen ((char *) s, "r");
21962       if (new_fp == 0)
21963         {
21964           errmsg ("Couldn't open script file %s", s);
21965           vec_free (s);
21966           return -99;
21967         }
21968     }
21969   else
21970     {
21971       errmsg ("Missing script name");
21972       return -99;
21973     }
21974
21975   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21976   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21977   save_ifp = vam->ifp;
21978   save_line_number = vam->input_line_number;
21979   save_current_file = (char *) vam->current_file;
21980
21981   vam->input_line_number = 0;
21982   vam->ifp = new_fp;
21983   vam->current_file = s;
21984   do_one_file (vam);
21985
21986   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21987   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21988   vam->ifp = save_ifp;
21989   vam->input_line_number = save_line_number;
21990   vam->current_file = (u8 *) save_current_file;
21991   vec_free (s);
21992
21993   return 0;
21994 #else
21995   clib_warning ("use the exec command...");
21996   return -99;
21997 #endif
21998 }
21999
22000 static int
22001 echo (vat_main_t * vam)
22002 {
22003   print (vam->ofp, "%v", vam->input->buffer);
22004   return 0;
22005 }
22006
22007 /* List of API message constructors, CLI names map to api_xxx */
22008 #define foreach_vpe_api_msg                                             \
22009 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22010 _(sw_interface_dump,"")                                                 \
22011 _(sw_interface_set_flags,                                               \
22012   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22013 _(sw_interface_add_del_address,                                         \
22014   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22015 _(sw_interface_set_rx_mode,                                             \
22016   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22017 _(sw_interface_set_table,                                               \
22018   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22019 _(sw_interface_set_mpls_enable,                                         \
22020   "<intfc> | sw_if_index [disable | dis]")                              \
22021 _(sw_interface_set_vpath,                                               \
22022   "<intfc> | sw_if_index <id> enable | disable")                        \
22023 _(sw_interface_set_vxlan_bypass,                                        \
22024   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22025 _(sw_interface_set_geneve_bypass,                                       \
22026   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22027 _(sw_interface_set_l2_xconnect,                                         \
22028   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22029   "enable | disable")                                                   \
22030 _(sw_interface_set_l2_bridge,                                           \
22031   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22032   "[shg <split-horizon-group>] [bvi]\n"                                 \
22033   "enable | disable")                                                   \
22034 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22035 _(bridge_domain_add_del,                                                \
22036   "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") \
22037 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22038 _(l2fib_add_del,                                                        \
22039   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22040 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22041 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22042 _(l2_flags,                                                             \
22043   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22044 _(bridge_flags,                                                         \
22045   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22046 _(tap_connect,                                                          \
22047   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22048 _(tap_modify,                                                           \
22049   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22050 _(tap_delete,                                                           \
22051   "<vpp-if-name> | sw_if_index <id>")                                   \
22052 _(sw_interface_tap_dump, "")                                            \
22053 _(ip_table_add_del,                                                     \
22054   "table-id <n> [ipv6]\n")                                              \
22055 _(ip_add_del_route,                                                     \
22056   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22057   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22058   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22059   "[multipath] [count <n>]")                                            \
22060 _(ip_mroute_add_del,                                                    \
22061   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22062   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22063 _(mpls_table_add_del,                                                   \
22064   "table-id <n>\n")                                                     \
22065 _(mpls_route_add_del,                                                   \
22066   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22067   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22068   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22069   "[multipath] [count <n>]")                                            \
22070 _(mpls_ip_bind_unbind,                                                  \
22071   "<label> <addr/len>")                                                 \
22072 _(mpls_tunnel_add_del,                                                  \
22073   " via <addr> [table-id <n>]\n"                                        \
22074   "sw_if_index <id>] [l2]  [del]")                                      \
22075 _(proxy_arp_add_del,                                                    \
22076   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22077 _(proxy_arp_intfc_enable_disable,                                       \
22078   "<intfc> | sw_if_index <id> enable | disable")                        \
22079 _(sw_interface_set_unnumbered,                                          \
22080   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22081 _(ip_neighbor_add_del,                                                  \
22082   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22083   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22084 _(reset_vrf, "vrf <id> [ipv6]")                                         \
22085 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22086 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22087   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22088   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22089   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22090 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22091 _(reset_fib, "vrf <n> [ipv6]")                                          \
22092 _(dhcp_proxy_config,                                                    \
22093   "svr <v46-address> src <v46-address>\n"                               \
22094    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22095 _(dhcp_proxy_set_vss,                                                   \
22096   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22097 _(dhcp_proxy_dump, "ip6")                                               \
22098 _(dhcp_client_config,                                                   \
22099   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22100 _(set_ip_flow_hash,                                                     \
22101   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22102 _(sw_interface_ip6_enable_disable,                                      \
22103   "<intfc> | sw_if_index <id> enable | disable")                        \
22104 _(sw_interface_ip6_set_link_local_address,                              \
22105   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22106 _(ip6nd_proxy_add_del,                                                  \
22107   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22108 _(ip6nd_proxy_dump, "")                                                 \
22109 _(sw_interface_ip6nd_ra_prefix,                                         \
22110   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22111   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22112   "[nolink] [isno]")                                                    \
22113 _(sw_interface_ip6nd_ra_config,                                         \
22114   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22115   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22116   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22117 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22118 _(l2_patch_add_del,                                                     \
22119   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22120   "enable | disable")                                                   \
22121 _(sr_localsid_add_del,                                                  \
22122   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22123   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22124 _(classify_add_del_table,                                               \
22125   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22126   " [del] [del-chain] mask <mask-value>\n"                              \
22127   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22128   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22129 _(classify_add_del_session,                                             \
22130   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22131   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22132   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22133   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22134 _(classify_set_interface_ip_table,                                      \
22135   "<intfc> | sw_if_index <nn> table <nn>")                              \
22136 _(classify_set_interface_l2_tables,                                     \
22137   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22138   "  [other-table <nn>]")                                               \
22139 _(get_node_index, "node <node-name")                                    \
22140 _(add_node_next, "node <node-name> next <next-node-name>")              \
22141 _(l2tpv3_create_tunnel,                                                 \
22142   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22143   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22144   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22145 _(l2tpv3_set_tunnel_cookies,                                            \
22146   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22147   "[new_remote_cookie <nn>]\n")                                         \
22148 _(l2tpv3_interface_enable_disable,                                      \
22149   "<intfc> | sw_if_index <nn> enable | disable")                        \
22150 _(l2tpv3_set_lookup_key,                                                \
22151   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22152 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22153 _(vxlan_add_del_tunnel,                                                 \
22154   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22155   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22156   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22157 _(geneve_add_del_tunnel,                                                \
22158   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22159   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22160   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22161 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22162 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22163 _(gre_add_del_tunnel,                                                   \
22164   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22165 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22166 _(l2_fib_clear_table, "")                                               \
22167 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22168 _(l2_interface_vlan_tag_rewrite,                                        \
22169   "<intfc> | sw_if_index <nn> \n"                                       \
22170   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22171   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22172 _(create_vhost_user_if,                                                 \
22173         "socket <filename> [server] [renumber <dev_instance>] "         \
22174         "[mac <mac_address>]")                                          \
22175 _(modify_vhost_user_if,                                                 \
22176         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22177         "[server] [renumber <dev_instance>]")                           \
22178 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22179 _(sw_interface_vhost_user_dump, "")                                     \
22180 _(show_version, "")                                                     \
22181 _(vxlan_gpe_add_del_tunnel,                                             \
22182   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22183   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22184   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22185   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22186 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22187 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22188 _(interface_name_renumber,                                              \
22189   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22190 _(input_acl_set_interface,                                              \
22191   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22192   "  [l2-table <nn>] [del]")                                            \
22193 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22194 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22195 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22196 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22197 _(ip_dump, "ipv4 | ipv6")                                               \
22198 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22199 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22200   "  spid_id <n> ")                                                     \
22201 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22202   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22203   "  integ_alg <alg> integ_key <hex>")                                  \
22204 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22205   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22206   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22207   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22208 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22209 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22210   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22211   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22212   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22213 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22214 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22215   "  <alg> <hex>\n")                                                    \
22216 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22217 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22218 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22219   "(auth_data 0x<data> | auth_data <data>)")                            \
22220 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22221   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22222 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22223   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22224   "(local|remote)")                                                     \
22225 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22226 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22227 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22228 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22229 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22230 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22231 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22232 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22233 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22234 _(delete_loopback,"sw_if_index <nn>")                                   \
22235 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22236 _(map_add_domain,                                                       \
22237   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22238   "ip6-src <ip6addr> "                                                  \
22239   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22240 _(map_del_domain, "index <n>")                                          \
22241 _(map_add_del_rule,                                                     \
22242   "index <n> psid <n> dst <ip6addr> [del]")                             \
22243 _(map_domain_dump, "")                                                  \
22244 _(map_rule_dump, "index <map-domain>")                                  \
22245 _(want_interface_events,  "enable|disable")                             \
22246 _(want_stats,"enable|disable")                                          \
22247 _(get_first_msg_id, "client <name>")                                    \
22248 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22249 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22250   "fib-id <nn> [ip4][ip6][default]")                                    \
22251 _(get_node_graph, " ")                                                  \
22252 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22253 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22254 _(ioam_disable, "")                                                     \
22255 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22256                             " sw_if_index <sw_if_index> p <priority> "  \
22257                             "w <weight>] [del]")                        \
22258 _(one_add_del_locator, "locator-set <locator_name> "                    \
22259                         "iface <intf> | sw_if_index <sw_if_index> "     \
22260                         "p <priority> w <weight> [del]")                \
22261 _(one_add_del_local_eid,"vni <vni> eid "                                \
22262                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22263                          "locator-set <locator_name> [del]"             \
22264                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22265 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22266 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22267 _(one_enable_disable, "enable|disable")                                 \
22268 _(one_map_register_enable_disable, "enable|disable")                    \
22269 _(one_map_register_fallback_threshold, "<value>")                       \
22270 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22271 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22272                                "[seid <seid>] "                         \
22273                                "rloc <locator> p <prio> "               \
22274                                "w <weight> [rloc <loc> ... ] "          \
22275                                "action <action> [del-all]")             \
22276 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22277                           "<local-eid>")                                \
22278 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22279 _(one_use_petr, "ip-address> | disable")                                \
22280 _(one_map_request_mode, "src-dst|dst-only")                             \
22281 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22282 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22283 _(one_locator_set_dump, "[local | remote]")                             \
22284 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22285 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22286                        "[local] | [remote]")                            \
22287 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22288 _(one_ndp_bd_get, "")                                                   \
22289 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22290 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22291 _(one_l2_arp_bd_get, "")                                                \
22292 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22293 _(one_stats_enable_disable, "enable|disalbe")                           \
22294 _(show_one_stats_enable_disable, "")                                    \
22295 _(one_eid_table_vni_dump, "")                                           \
22296 _(one_eid_table_map_dump, "l2|l3")                                      \
22297 _(one_map_resolver_dump, "")                                            \
22298 _(one_map_server_dump, "")                                              \
22299 _(one_adjacencies_get, "vni <vni>")                                     \
22300 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22301 _(show_one_rloc_probe_state, "")                                        \
22302 _(show_one_map_register_state, "")                                      \
22303 _(show_one_status, "")                                                  \
22304 _(one_stats_dump, "")                                                   \
22305 _(one_stats_flush, "")                                                  \
22306 _(one_get_map_request_itr_rlocs, "")                                    \
22307 _(one_map_register_set_ttl, "<ttl>")                                    \
22308 _(one_set_transport_protocol, "udp|api")                                \
22309 _(one_get_transport_protocol, "")                                       \
22310 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22311 _(one_show_xtr_mode, "")                                                \
22312 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22313 _(one_show_pitr_mode, "")                                               \
22314 _(one_enable_disable_petr_mode, "enable|disable")                       \
22315 _(one_show_petr_mode, "")                                               \
22316 _(show_one_nsh_mapping, "")                                             \
22317 _(show_one_pitr, "")                                                    \
22318 _(show_one_use_petr, "")                                                \
22319 _(show_one_map_request_mode, "")                                        \
22320 _(show_one_map_register_ttl, "")                                        \
22321 _(show_one_map_register_fallback_threshold, "")                         \
22322 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22323                             " sw_if_index <sw_if_index> p <priority> "  \
22324                             "w <weight>] [del]")                        \
22325 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22326                         "iface <intf> | sw_if_index <sw_if_index> "     \
22327                         "p <priority> w <weight> [del]")                \
22328 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22329                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22330                          "locator-set <locator_name> [del]"             \
22331                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22332 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22333 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22334 _(lisp_enable_disable, "enable|disable")                                \
22335 _(lisp_map_register_enable_disable, "enable|disable")                   \
22336 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22337 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22338                                "[seid <seid>] "                         \
22339                                "rloc <locator> p <prio> "               \
22340                                "w <weight> [rloc <loc> ... ] "          \
22341                                "action <action> [del-all]")             \
22342 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22343                           "<local-eid>")                                \
22344 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22345 _(lisp_use_petr, "<ip-address> | disable")                              \
22346 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22347 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22348 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22349 _(lisp_locator_set_dump, "[local | remote]")                            \
22350 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22351 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22352                        "[local] | [remote]")                            \
22353 _(lisp_eid_table_vni_dump, "")                                          \
22354 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22355 _(lisp_map_resolver_dump, "")                                           \
22356 _(lisp_map_server_dump, "")                                             \
22357 _(lisp_adjacencies_get, "vni <vni>")                                    \
22358 _(gpe_fwd_entry_vnis_get, "")                                           \
22359 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22360 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22361                                 "[table <table-id>]")                   \
22362 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22363 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22364 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22365 _(gpe_get_encap_mode, "")                                               \
22366 _(lisp_gpe_add_del_iface, "up|down")                                    \
22367 _(lisp_gpe_enable_disable, "enable|disable")                            \
22368 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22369   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22370 _(show_lisp_rloc_probe_state, "")                                       \
22371 _(show_lisp_map_register_state, "")                                     \
22372 _(show_lisp_status, "")                                                 \
22373 _(lisp_get_map_request_itr_rlocs, "")                                   \
22374 _(show_lisp_pitr, "")                                                   \
22375 _(show_lisp_use_petr, "")                                               \
22376 _(show_lisp_map_request_mode, "")                                       \
22377 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22378 _(af_packet_delete, "name <host interface name>")                       \
22379 _(policer_add_del, "name <policer name> <params> [del]")                \
22380 _(policer_dump, "[name <policer name>]")                                \
22381 _(policer_classify_set_interface,                                       \
22382   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22383   "  [l2-table <nn>] [del]")                                            \
22384 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22385 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22386     "[master|slave]")                                                   \
22387 _(netmap_delete, "name <interface name>")                               \
22388 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22389 _(mpls_fib_dump, "")                                                    \
22390 _(classify_table_ids, "")                                               \
22391 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22392 _(classify_table_info, "table_id <nn>")                                 \
22393 _(classify_session_dump, "table_id <nn>")                               \
22394 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22395     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22396     "[template_interval <nn>] [udp_checksum]")                          \
22397 _(ipfix_exporter_dump, "")                                              \
22398 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22399 _(ipfix_classify_stream_dump, "")                                       \
22400 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22401 _(ipfix_classify_table_dump, "")                                        \
22402 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22403 _(sw_interface_span_dump, "[l2]")                                           \
22404 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22405 _(pg_create_interface, "if_id <nn>")                                    \
22406 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22407 _(pg_enable_disable, "[stream <id>] disable")                           \
22408 _(ip_source_and_port_range_check_add_del,                               \
22409   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22410 _(ip_source_and_port_range_check_interface_add_del,                     \
22411   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22412   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22413 _(ipsec_gre_add_del_tunnel,                                             \
22414   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22415 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22416 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22417 _(l2_interface_pbb_tag_rewrite,                                         \
22418   "<intfc> | sw_if_index <nn> \n"                                       \
22419   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22420   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22421 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22422 _(flow_classify_set_interface,                                          \
22423   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22424 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22425 _(ip_fib_dump, "")                                                      \
22426 _(ip_mfib_dump, "")                                                     \
22427 _(ip6_fib_dump, "")                                                     \
22428 _(ip6_mfib_dump, "")                                                    \
22429 _(feature_enable_disable, "arc_name <arc_name> "                        \
22430   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22431 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22432 "[disable]")                                                            \
22433 _(l2_xconnect_dump, "")                                                 \
22434 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22435 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22436 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22437 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22438 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22439 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22440 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22441   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22442 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22443 _(memfd_segment_create,"size <nnn>")                                    \
22444 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22445 _(dns_enable_disable, "[enable][disable]")                              \
22446 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22447 _(dns_resolve_name, "<hostname>")                                       \
22448 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22449 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22450 _(dns_resolve_name, "<hostname>")                                       \
22451 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22452   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22453
22454 /* List of command functions, CLI names map directly to functions */
22455 #define foreach_cli_function                                    \
22456 _(comment, "usage: comment <ignore-rest-of-line>")              \
22457 _(dump_interface_table, "usage: dump_interface_table")          \
22458 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22459 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22460 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22461 _(dump_stats_table, "usage: dump_stats_table")                  \
22462 _(dump_macro_table, "usage: dump_macro_table ")                 \
22463 _(dump_node_table, "usage: dump_node_table")                    \
22464 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22465 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22466 _(echo, "usage: echo <message>")                                \
22467 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22468 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22469 _(help, "usage: help")                                          \
22470 _(q, "usage: quit")                                             \
22471 _(quit, "usage: quit")                                          \
22472 _(search_node_table, "usage: search_node_table <name>...")      \
22473 _(set, "usage: set <variable-name> <value>")                    \
22474 _(script, "usage: script <file-name>")                          \
22475 _(unset, "usage: unset <variable-name>")
22476 #define _(N,n)                                  \
22477     static void vl_api_##n##_t_handler_uni      \
22478     (vl_api_##n##_t * mp)                       \
22479     {                                           \
22480         vat_main_t * vam = &vat_main;           \
22481         if (vam->json_output) {                 \
22482             vl_api_##n##_t_handler_json(mp);    \
22483         } else {                                \
22484             vl_api_##n##_t_handler(mp);         \
22485         }                                       \
22486     }
22487 foreach_vpe_api_reply_msg;
22488 #if VPP_API_TEST_BUILTIN == 0
22489 foreach_standalone_reply_msg;
22490 #endif
22491 #undef _
22492
22493 void
22494 vat_api_hookup (vat_main_t * vam)
22495 {
22496 #define _(N,n)                                                  \
22497     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22498                            vl_api_##n##_t_handler_uni,          \
22499                            vl_noop_handler,                     \
22500                            vl_api_##n##_t_endian,               \
22501                            vl_api_##n##_t_print,                \
22502                            sizeof(vl_api_##n##_t), 1);
22503   foreach_vpe_api_reply_msg;
22504 #if VPP_API_TEST_BUILTIN == 0
22505   foreach_standalone_reply_msg;
22506 #endif
22507 #undef _
22508
22509 #if (VPP_API_TEST_BUILTIN==0)
22510   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22511
22512   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22513
22514   vam->function_by_name = hash_create_string (0, sizeof (uword));
22515
22516   vam->help_by_name = hash_create_string (0, sizeof (uword));
22517 #endif
22518
22519   /* API messages we can send */
22520 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22521   foreach_vpe_api_msg;
22522 #undef _
22523
22524   /* Help strings */
22525 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22526   foreach_vpe_api_msg;
22527 #undef _
22528
22529   /* CLI functions */
22530 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22531   foreach_cli_function;
22532 #undef _
22533
22534   /* Help strings */
22535 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22536   foreach_cli_function;
22537 #undef _
22538 }
22539
22540 #if VPP_API_TEST_BUILTIN
22541 static clib_error_t *
22542 vat_api_hookup_shim (vlib_main_t * vm)
22543 {
22544   vat_api_hookup (&vat_main);
22545   return 0;
22546 }
22547
22548 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22549 #endif
22550
22551 /*
22552  * fd.io coding-style-patch-verification: ON
22553  *
22554  * Local Variables:
22555  * eval: (c-set-style "gnu")
22556  * End:
22557  */