session: swap appns secret to host byte order
[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 (u64 * mac)
722 {
723   u64 tmp = *mac;
724
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728   *mac = tmp;
729 }
730
731 static void vl_api_create_loopback_reply_t_handler
732   (vl_api_create_loopback_reply_t * mp)
733 {
734   vat_main_t *vam = &vat_main;
735   i32 retval = ntohl (mp->retval);
736
737   vam->retval = retval;
738   vam->regenerate_interface_table = 1;
739   vam->sw_if_index = ntohl (mp->sw_if_index);
740   vam->result_ready = 1;
741 }
742
743 static void vl_api_create_loopback_reply_t_handler_json
744   (vl_api_create_loopback_reply_t * mp)
745 {
746   vat_main_t *vam = &vat_main;
747   vat_json_node_t node;
748
749   vat_json_init_object (&node);
750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
752
753   vat_json_print (vam->ofp, &node);
754   vat_json_free (&node);
755   vam->retval = ntohl (mp->retval);
756   vam->result_ready = 1;
757 }
758
759 static void vl_api_create_loopback_instance_reply_t_handler
760   (vl_api_create_loopback_instance_reply_t * mp)
761 {
762   vat_main_t *vam = &vat_main;
763   i32 retval = ntohl (mp->retval);
764
765   vam->retval = retval;
766   vam->regenerate_interface_table = 1;
767   vam->sw_if_index = ntohl (mp->sw_if_index);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_loopback_instance_reply_t_handler_json
772   (vl_api_create_loopback_instance_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   vat_json_node_t node;
776
777   vat_json_init_object (&node);
778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
779   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
780
781   vat_json_print (vam->ofp, &node);
782   vat_json_free (&node);
783   vam->retval = ntohl (mp->retval);
784   vam->result_ready = 1;
785 }
786
787 static void vl_api_af_packet_create_reply_t_handler
788   (vl_api_af_packet_create_reply_t * mp)
789 {
790   vat_main_t *vam = &vat_main;
791   i32 retval = ntohl (mp->retval);
792
793   vam->retval = retval;
794   vam->regenerate_interface_table = 1;
795   vam->sw_if_index = ntohl (mp->sw_if_index);
796   vam->result_ready = 1;
797 }
798
799 static void vl_api_af_packet_create_reply_t_handler_json
800   (vl_api_af_packet_create_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   vat_json_node_t node;
804
805   vat_json_init_object (&node);
806   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
807   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
808
809   vat_json_print (vam->ofp, &node);
810   vat_json_free (&node);
811
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_create_vlan_subif_reply_t_handler
817   (vl_api_create_vlan_subif_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_create_vlan_subif_reply_t_handler_json
829   (vl_api_create_vlan_subif_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_subif_reply_t_handler
846   (vl_api_create_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_subif_reply_t_handler_json
858   (vl_api_create_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_interface_name_renumber_reply_t_handler
875   (vl_api_interface_name_renumber_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->result_ready = 1;
883 }
884
885 static void vl_api_interface_name_renumber_reply_t_handler_json
886   (vl_api_interface_name_renumber_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890
891   vat_json_init_object (&node);
892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
893
894   vat_json_print (vam->ofp, &node);
895   vat_json_free (&node);
896
897   vam->retval = ntohl (mp->retval);
898   vam->result_ready = 1;
899 }
900
901 /*
902  * Special-case: build the interface table, maintain
903  * the next loopback sw_if_index vbl.
904  */
905 static void vl_api_sw_interface_details_t_handler
906   (vl_api_sw_interface_details_t * mp)
907 {
908   vat_main_t *vam = &vat_main;
909   u8 *s = format (0, "%s%c", mp->interface_name, 0);
910
911   hash_set_mem (vam->sw_if_index_by_interface_name, s,
912                 ntohl (mp->sw_if_index));
913
914   /* In sub interface case, fill the sub interface table entry */
915   if (mp->sw_if_index != mp->sup_sw_if_index)
916     {
917       sw_interface_subif_t *sub = NULL;
918
919       vec_add2 (vam->sw_if_subif_table, sub, 1);
920
921       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
922       strncpy ((char *) sub->interface_name, (char *) s,
923                vec_len (sub->interface_name));
924       sub->sw_if_index = ntohl (mp->sw_if_index);
925       sub->sub_id = ntohl (mp->sub_id);
926
927       sub->sub_dot1ad = mp->sub_dot1ad;
928       sub->sub_number_of_tags = mp->sub_number_of_tags;
929       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
930       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
931       sub->sub_exact_match = mp->sub_exact_match;
932       sub->sub_default = mp->sub_default;
933       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
934       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
935
936       /* vlan tag rewrite */
937       sub->vtr_op = ntohl (mp->vtr_op);
938       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
939       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
940       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
941     }
942 }
943
944 static void vl_api_sw_interface_details_t_handler_json
945   (vl_api_sw_interface_details_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   vat_json_node_t *node = NULL;
949
950   if (VAT_JSON_ARRAY != vam->json_tree.type)
951     {
952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
953       vat_json_init_array (&vam->json_tree);
954     }
955   node = vat_json_array_add (&vam->json_tree);
956
957   vat_json_init_object (node);
958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
959   vat_json_object_add_uint (node, "sup_sw_if_index",
960                             ntohl (mp->sup_sw_if_index));
961   vat_json_object_add_uint (node, "l2_address_length",
962                             ntohl (mp->l2_address_length));
963   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
964                              sizeof (mp->l2_address));
965   vat_json_object_add_string_copy (node, "interface_name",
966                                    mp->interface_name);
967   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
968   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
969   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
970   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
971   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
972   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
973   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
974   vat_json_object_add_uint (node, "sub_number_of_tags",
975                             mp->sub_number_of_tags);
976   vat_json_object_add_uint (node, "sub_outer_vlan_id",
977                             ntohs (mp->sub_outer_vlan_id));
978   vat_json_object_add_uint (node, "sub_inner_vlan_id",
979                             ntohs (mp->sub_inner_vlan_id));
980   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
981   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
982   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
983                             mp->sub_outer_vlan_id_any);
984   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
985                             mp->sub_inner_vlan_id_any);
986   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
987   vat_json_object_add_uint (node, "vtr_push_dot1q",
988                             ntohl (mp->vtr_push_dot1q));
989   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
990   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
991   if (mp->sub_dot1ah)
992     {
993       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
994                                        format (0, "%U",
995                                                format_ethernet_address,
996                                                &mp->b_dmac));
997       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
998                                        format (0, "%U",
999                                                format_ethernet_address,
1000                                                &mp->b_smac));
1001       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1002       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1003     }
1004 }
1005
1006 #if VPP_API_TEST_BUILTIN == 0
1007 static void vl_api_sw_interface_event_t_handler
1008   (vl_api_sw_interface_event_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   if (vam->interface_event_display)
1012     errmsg ("interface flags: sw_if_index %d %s %s",
1013             ntohl (mp->sw_if_index),
1014             mp->admin_up_down ? "admin-up" : "admin-down",
1015             mp->link_up_down ? "link-up" : "link-down");
1016 }
1017 #endif
1018
1019 static void vl_api_sw_interface_event_t_handler_json
1020   (vl_api_sw_interface_event_t * mp)
1021 {
1022   /* JSON output not supported */
1023 }
1024
1025 static void
1026 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030
1031   vam->retval = retval;
1032   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033   vam->result_ready = 1;
1034 }
1035
1036 static void
1037 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t node;
1041   api_main_t *am = &api_main;
1042   void *oldheap;
1043   u8 *reply;
1044
1045   vat_json_init_object (&node);
1046   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1047   vat_json_object_add_uint (&node, "reply_in_shmem",
1048                             ntohl (mp->reply_in_shmem));
1049   /* Toss the shared-memory original... */
1050   pthread_mutex_lock (&am->vlib_rp->mutex);
1051   oldheap = svm_push_data_heap (am->vlib_rp);
1052
1053   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1054   vec_free (reply);
1055
1056   svm_pop_heap (oldheap);
1057   pthread_mutex_unlock (&am->vlib_rp->mutex);
1058
1059   vat_json_print (vam->ofp, &node);
1060   vat_json_free (&node);
1061
1062   vam->retval = ntohl (mp->retval);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   i32 retval = ntohl (mp->retval);
1071   u32 length = ntohl (mp->length);
1072
1073   vec_reset_length (vam->cmd_reply);
1074
1075   vam->retval = retval;
1076   if (retval == 0)
1077     {
1078       vec_validate (vam->cmd_reply, length);
1079       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1080       vam->cmd_reply[length] = 0;
1081     }
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vec_reset_length (vam->cmd_reply);
1092
1093   vat_json_init_object (&node);
1094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1095   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1096
1097   vat_json_print (vam->ofp, &node);
1098   vat_json_free (&node);
1099
1100   vam->retval = ntohl (mp->retval);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void vl_api_classify_add_del_table_reply_t_handler
1105   (vl_api_classify_add_del_table_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   i32 retval = ntohl (mp->retval);
1109   if (vam->async_mode)
1110     {
1111       vam->async_errors += (retval < 0);
1112     }
1113   else
1114     {
1115       vam->retval = retval;
1116       if (retval == 0 &&
1117           ((mp->new_table_index != 0xFFFFFFFF) ||
1118            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1119            (mp->match_n_vectors != 0xFFFFFFFF)))
1120         /*
1121          * Note: this is just barely thread-safe, depends on
1122          * the main thread spinning waiting for an answer...
1123          */
1124         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1125                 ntohl (mp->new_table_index),
1126                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1127       vam->result_ready = 1;
1128     }
1129 }
1130
1131 static void vl_api_classify_add_del_table_reply_t_handler_json
1132   (vl_api_classify_add_del_table_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "new_table_index",
1140                             ntohl (mp->new_table_index));
1141   vat_json_object_add_uint (&node, "skip_n_vectors",
1142                             ntohl (mp->skip_n_vectors));
1143   vat_json_object_add_uint (&node, "match_n_vectors",
1144                             ntohl (mp->match_n_vectors));
1145
1146   vat_json_print (vam->ofp, &node);
1147   vat_json_free (&node);
1148
1149   vam->retval = ntohl (mp->retval);
1150   vam->result_ready = 1;
1151 }
1152
1153 static void vl_api_get_node_index_reply_t_handler
1154   (vl_api_get_node_index_reply_t * mp)
1155 {
1156   vat_main_t *vam = &vat_main;
1157   i32 retval = ntohl (mp->retval);
1158   if (vam->async_mode)
1159     {
1160       vam->async_errors += (retval < 0);
1161     }
1162   else
1163     {
1164       vam->retval = retval;
1165       if (retval == 0)
1166         errmsg ("node index %d", ntohl (mp->node_index));
1167       vam->result_ready = 1;
1168     }
1169 }
1170
1171 static void vl_api_get_node_index_reply_t_handler_json
1172   (vl_api_get_node_index_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176
1177   vat_json_init_object (&node);
1178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1179   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1180
1181   vat_json_print (vam->ofp, &node);
1182   vat_json_free (&node);
1183
1184   vam->retval = ntohl (mp->retval);
1185   vam->result_ready = 1;
1186 }
1187
1188 static void vl_api_get_next_index_reply_t_handler
1189   (vl_api_get_next_index_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   i32 retval = ntohl (mp->retval);
1193   if (vam->async_mode)
1194     {
1195       vam->async_errors += (retval < 0);
1196     }
1197   else
1198     {
1199       vam->retval = retval;
1200       if (retval == 0)
1201         errmsg ("next node index %d", ntohl (mp->next_index));
1202       vam->result_ready = 1;
1203     }
1204 }
1205
1206 static void vl_api_get_next_index_reply_t_handler_json
1207   (vl_api_get_next_index_reply_t * mp)
1208 {
1209   vat_main_t *vam = &vat_main;
1210   vat_json_node_t node;
1211
1212   vat_json_init_object (&node);
1213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1214   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_add_node_next_reply_t_handler
1224   (vl_api_add_node_next_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("next index %d", ntohl (mp->next_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_add_node_next_reply_t_handler_json
1242   (vl_api_add_node_next_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_show_version_reply_t_handler
1259   (vl_api_show_version_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263
1264   if (retval >= 0)
1265     {
1266       errmsg ("        program: %s", mp->program);
1267       errmsg ("        version: %s", mp->version);
1268       errmsg ("     build date: %s", mp->build_date);
1269       errmsg ("build directory: %s", mp->build_directory);
1270     }
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void vl_api_show_version_reply_t_handler_json
1276   (vl_api_show_version_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t node;
1280
1281   vat_json_init_object (&node);
1282   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1283   vat_json_object_add_string_copy (&node, "program", mp->program);
1284   vat_json_object_add_string_copy (&node, "version", mp->version);
1285   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1286   vat_json_object_add_string_copy (&node, "build_directory",
1287                                    mp->build_directory);
1288
1289   vat_json_print (vam->ofp, &node);
1290   vat_json_free (&node);
1291
1292   vam->retval = ntohl (mp->retval);
1293   vam->result_ready = 1;
1294 }
1295
1296 static void
1297 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1298 {
1299   u32 sw_if_index = ntohl (mp->sw_if_index);
1300   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1301           mp->mac_ip ? "mac/ip binding" : "address resolution",
1302           ntohl (mp->pid), format_ip4_address, &mp->address,
1303           format_ethernet_address, mp->new_mac, sw_if_index);
1304 }
1305
1306 static void
1307 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1308 {
1309   /* JSON output not supported */
1310 }
1311
1312 static void
1313 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1314 {
1315   u32 sw_if_index = ntohl (mp->sw_if_index);
1316   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1317           mp->mac_ip ? "mac/ip binding" : "address resolution",
1318           ntohl (mp->pid), format_ip6_address, mp->address,
1319           format_ethernet_address, mp->new_mac, sw_if_index);
1320 }
1321
1322 static void
1323 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1324 {
1325   /* JSON output not supported */
1326 }
1327
1328 static void
1329 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1330 {
1331   u32 n_macs = ntohl (mp->n_macs);
1332   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1333           ntohl (mp->pid), mp->client_index, n_macs);
1334   int i;
1335   for (i = 0; i < n_macs; i++)
1336     {
1337       vl_api_mac_entry_t *mac = &mp->mac[i];
1338       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1339               i + 1, ntohl (mac->sw_if_index),
1340               format_ethernet_address, mac->mac_addr, mac->is_del);
1341       if (i == 1000)
1342         break;
1343     }
1344 }
1345
1346 static void
1347 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1348 {
1349   /* JSON output not supported */
1350 }
1351
1352 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1353 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1354
1355 /*
1356  * Special-case: build the bridge domain table, maintain
1357  * the next bd id vbl.
1358  */
1359 static void vl_api_bridge_domain_details_t_handler
1360   (vl_api_bridge_domain_details_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1364   int i;
1365
1366   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1367          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1368
1369   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1370          ntohl (mp->bd_id), mp->learn, mp->forward,
1371          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1372
1373   if (n_sw_ifs)
1374     {
1375       vl_api_bridge_domain_sw_if_t *sw_ifs;
1376       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1377              "Interface Name");
1378
1379       sw_ifs = mp->sw_if_details;
1380       for (i = 0; i < n_sw_ifs; i++)
1381         {
1382           u8 *sw_if_name = 0;
1383           u32 sw_if_index;
1384           hash_pair_t *p;
1385
1386           sw_if_index = ntohl (sw_ifs->sw_if_index);
1387
1388           /* *INDENT-OFF* */
1389           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1390                              ({
1391                                if ((u32) p->value[0] == sw_if_index)
1392                                  {
1393                                    sw_if_name = (u8 *)(p->key);
1394                                    break;
1395                                  }
1396                              }));
1397           /* *INDENT-ON* */
1398           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1399                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1400                  "sw_if_index not found!");
1401
1402           sw_ifs++;
1403         }
1404     }
1405 }
1406
1407 static void vl_api_bridge_domain_details_t_handler_json
1408   (vl_api_bridge_domain_details_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t *node, *array = NULL;
1412   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1413
1414   if (VAT_JSON_ARRAY != vam->json_tree.type)
1415     {
1416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1417       vat_json_init_array (&vam->json_tree);
1418     }
1419   node = vat_json_array_add (&vam->json_tree);
1420
1421   vat_json_init_object (node);
1422   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1423   vat_json_object_add_uint (node, "flood", mp->flood);
1424   vat_json_object_add_uint (node, "forward", mp->forward);
1425   vat_json_object_add_uint (node, "learn", mp->learn);
1426   vat_json_object_add_uint (node, "bvi_sw_if_index",
1427                             ntohl (mp->bvi_sw_if_index));
1428   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1429   array = vat_json_object_add (node, "sw_if");
1430   vat_json_init_array (array);
1431
1432
1433
1434   if (n_sw_ifs)
1435     {
1436       vl_api_bridge_domain_sw_if_t *sw_ifs;
1437       int i;
1438
1439       sw_ifs = mp->sw_if_details;
1440       for (i = 0; i < n_sw_ifs; i++)
1441         {
1442           node = vat_json_array_add (array);
1443           vat_json_init_object (node);
1444           vat_json_object_add_uint (node, "sw_if_index",
1445                                     ntohl (sw_ifs->sw_if_index));
1446           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1447           sw_ifs++;
1448         }
1449     }
1450 }
1451
1452 static void vl_api_control_ping_reply_t_handler
1453   (vl_api_control_ping_reply_t * mp)
1454 {
1455   vat_main_t *vam = &vat_main;
1456   i32 retval = ntohl (mp->retval);
1457   if (vam->async_mode)
1458     {
1459       vam->async_errors += (retval < 0);
1460     }
1461   else
1462     {
1463       vam->retval = retval;
1464       vam->result_ready = 1;
1465     }
1466   vam->socket_client_main.control_pings_outstanding--;
1467 }
1468
1469 static void vl_api_control_ping_reply_t_handler_json
1470   (vl_api_control_ping_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474
1475   if (VAT_JSON_NONE != vam->json_tree.type)
1476     {
1477       vat_json_print (vam->ofp, &vam->json_tree);
1478       vat_json_free (&vam->json_tree);
1479       vam->json_tree.type = VAT_JSON_NONE;
1480     }
1481   else
1482     {
1483       /* just print [] */
1484       vat_json_init_array (&vam->json_tree);
1485       vat_json_print (vam->ofp, &vam->json_tree);
1486       vam->json_tree.type = VAT_JSON_NONE;
1487     }
1488
1489   vam->retval = retval;
1490   vam->result_ready = 1;
1491 }
1492
1493 static void
1494   vl_api_bridge_domain_set_mac_age_reply_t_handler
1495   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518
1519   vat_json_print (vam->ofp, &node);
1520   vat_json_free (&node);
1521
1522   vam->retval = ntohl (mp->retval);
1523   vam->result_ready = 1;
1524 }
1525
1526 static void
1527 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   i32 retval = ntohl (mp->retval);
1531   if (vam->async_mode)
1532     {
1533       vam->async_errors += (retval < 0);
1534     }
1535   else
1536     {
1537       vam->retval = retval;
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_l2_flags_reply_t_handler_json
1543   (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1551                             ntohl (mp->resulting_feature_bitmap));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_bridge_flags_reply_t_handler
1561   (vl_api_bridge_flags_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler_json
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1585                             ntohl (mp->resulting_feature_bitmap));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_tap_connect_reply_t_handler
1595   (vl_api_tap_connect_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609
1610 }
1611
1612 static void vl_api_tap_connect_reply_t_handler_json
1613   (vl_api_tap_connect_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   vat_json_node_t node;
1617
1618   vat_json_init_object (&node);
1619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627
1628 }
1629
1630 static void
1631 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->sw_if_index = ntohl (mp->sw_if_index);
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_tap_modify_reply_t_handler_json
1648   (vl_api_tap_modify_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_tap_delete_reply_t_handler_json
1681   (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1697   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1713   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1721                             ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1731   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1748   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1765   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1781   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "fwd_entry_index",
1789                             clib_net_to_host_u32 (mp->fwd_entry_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 u8 *
1799 format_lisp_transport_protocol (u8 * s, va_list * args)
1800 {
1801   u32 proto = va_arg (*args, u32);
1802
1803   switch (proto)
1804     {
1805     case 1:
1806       return format (s, "udp");
1807     case 2:
1808       return format (s, "api");
1809     default:
1810       return 0;
1811     }
1812   return 0;
1813 }
1814
1815 static void vl_api_one_get_transport_protocol_reply_t_handler
1816   (vl_api_one_get_transport_protocol_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       u32 proto = mp->protocol;
1827       print (vam->ofp, "Transport protocol: %U",
1828              format_lisp_transport_protocol, proto);
1829       vam->retval = retval;
1830       vam->result_ready = 1;
1831     }
1832 }
1833
1834 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1835   (vl_api_one_get_transport_protocol_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   vat_json_node_t node;
1839   u8 *s;
1840
1841   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1842   vec_add1 (s, 0);
1843
1844   vat_json_init_object (&node);
1845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1846   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1847
1848   vec_free (s);
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_one_add_del_locator_set_reply_t_handler
1857   (vl_api_one_add_del_locator_set_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->result_ready = 1;
1869     }
1870 }
1871
1872 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1873   (vl_api_one_add_del_locator_set_reply_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   vat_json_node_t node;
1877
1878   vat_json_init_object (&node);
1879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1880   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1881
1882   vat_json_print (vam->ofp, &node);
1883   vat_json_free (&node);
1884
1885   vam->retval = ntohl (mp->retval);
1886   vam->result_ready = 1;
1887 }
1888
1889 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1890   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   i32 retval = ntohl (mp->retval);
1894   if (vam->async_mode)
1895     {
1896       vam->async_errors += (retval < 0);
1897     }
1898   else
1899     {
1900       vam->retval = retval;
1901       vam->sw_if_index = ntohl (mp->sw_if_index);
1902       vam->result_ready = 1;
1903     }
1904 }
1905
1906 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1907   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t node;
1911
1912   vat_json_init_object (&node);
1913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1914   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1915
1916   vat_json_print (vam->ofp, &node);
1917   vat_json_free (&node);
1918
1919   vam->retval = ntohl (mp->retval);
1920   vam->result_ready = 1;
1921 }
1922
1923 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1924   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   i32 retval = ntohl (mp->retval);
1928   if (vam->async_mode)
1929     {
1930       vam->async_errors += (retval < 0);
1931     }
1932   else
1933     {
1934       vam->retval = retval;
1935       vam->sw_if_index = ntohl (mp->sw_if_index);
1936       vam->result_ready = 1;
1937     }
1938 }
1939
1940 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
1941   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1942 {
1943   vat_main_t *vam = &vat_main;
1944   vat_json_node_t node;
1945
1946   vat_json_init_object (&node);
1947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1948   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1949
1950   vat_json_print (vam->ofp, &node);
1951   vat_json_free (&node);
1952
1953   vam->retval = ntohl (mp->retval);
1954   vam->result_ready = 1;
1955 }
1956
1957 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1958   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   i32 retval = ntohl (mp->retval);
1962   if (vam->async_mode)
1963     {
1964       vam->async_errors += (retval < 0);
1965     }
1966   else
1967     {
1968       vam->retval = retval;
1969       vam->sw_if_index = ntohl (mp->sw_if_index);
1970       vam->result_ready = 1;
1971     }
1972 }
1973
1974 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1975   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   vat_json_node_t node;
1979
1980   vat_json_init_object (&node);
1981   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1982   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1983
1984   vat_json_print (vam->ofp, &node);
1985   vat_json_free (&node);
1986
1987   vam->retval = ntohl (mp->retval);
1988   vam->result_ready = 1;
1989 }
1990
1991 static void vl_api_gre_add_del_tunnel_reply_t_handler
1992   (vl_api_gre_add_del_tunnel_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   i32 retval = ntohl (mp->retval);
1996   if (vam->async_mode)
1997     {
1998       vam->async_errors += (retval < 0);
1999     }
2000   else
2001     {
2002       vam->retval = retval;
2003       vam->sw_if_index = ntohl (mp->sw_if_index);
2004       vam->result_ready = 1;
2005     }
2006 }
2007
2008 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2009   (vl_api_gre_add_del_tunnel_reply_t * mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   vat_json_node_t node;
2013
2014   vat_json_init_object (&node);
2015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2016   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2017
2018   vat_json_print (vam->ofp, &node);
2019   vat_json_free (&node);
2020
2021   vam->retval = ntohl (mp->retval);
2022   vam->result_ready = 1;
2023 }
2024
2025 static void vl_api_create_vhost_user_if_reply_t_handler
2026   (vl_api_create_vhost_user_if_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   i32 retval = ntohl (mp->retval);
2030   if (vam->async_mode)
2031     {
2032       vam->async_errors += (retval < 0);
2033     }
2034   else
2035     {
2036       vam->retval = retval;
2037       vam->sw_if_index = ntohl (mp->sw_if_index);
2038       vam->result_ready = 1;
2039     }
2040 }
2041
2042 static void vl_api_create_vhost_user_if_reply_t_handler_json
2043   (vl_api_create_vhost_user_if_reply_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vat_json_node_t node;
2047
2048   vat_json_init_object (&node);
2049   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2050   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2051
2052   vat_json_print (vam->ofp, &node);
2053   vat_json_free (&node);
2054
2055   vam->retval = ntohl (mp->retval);
2056   vam->result_ready = 1;
2057 }
2058
2059 static clib_error_t *
2060 receive_fd_msg (int socket_fd, int *my_fd)
2061 {
2062   char msgbuf[16];
2063   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2064   struct msghdr mh = { 0 };
2065   struct iovec iov[1];
2066   ssize_t size;
2067   struct ucred *cr = 0;
2068   struct cmsghdr *cmsg;
2069   pid_t pid __attribute__ ((unused));
2070   uid_t uid __attribute__ ((unused));
2071   gid_t gid __attribute__ ((unused));
2072
2073   iov[0].iov_base = msgbuf;
2074   iov[0].iov_len = 5;
2075   mh.msg_iov = iov;
2076   mh.msg_iovlen = 1;
2077   mh.msg_control = ctl;
2078   mh.msg_controllen = sizeof (ctl);
2079
2080   memset (ctl, 0, sizeof (ctl));
2081
2082   /* receive the incoming message */
2083   size = recvmsg (socket_fd, &mh, 0);
2084   if (size != 5)
2085     {
2086       return (size == 0) ? clib_error_return (0, "disconnected") :
2087         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2088                                 socket_fd);
2089     }
2090
2091   cmsg = CMSG_FIRSTHDR (&mh);
2092   while (cmsg)
2093     {
2094       if (cmsg->cmsg_level == SOL_SOCKET)
2095         {
2096           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2097             {
2098               cr = (struct ucred *) CMSG_DATA (cmsg);
2099               uid = cr->uid;
2100               gid = cr->gid;
2101               pid = cr->pid;
2102             }
2103           else if (cmsg->cmsg_type == SCM_RIGHTS)
2104             {
2105               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2106             }
2107         }
2108       cmsg = CMSG_NXTHDR (&mh, cmsg);
2109     }
2110   return 0;
2111 }
2112
2113 static void vl_api_memfd_segment_create_reply_t_handler
2114   (vl_api_memfd_segment_create_reply_t * mp)
2115 {
2116   /* Dont bother in the builtin version */
2117 #if VPP_API_TEST_BUILTIN == 0
2118   vat_main_t *vam = &vat_main;
2119   api_main_t *am = &api_main;
2120   socket_client_main_t *scm = &vam->socket_client_main;
2121   int my_fd = -1;
2122   clib_error_t *error;
2123   memfd_private_t memfd;
2124   i32 retval = ntohl (mp->retval);
2125
2126   if (retval == 0)
2127     {
2128       error = receive_fd_msg (scm->socket_fd, &my_fd);
2129       if (error)
2130         {
2131           retval = -99;
2132           goto out;
2133         }
2134
2135       memset (&memfd, 0, sizeof (memfd));
2136       memfd.fd = my_fd;
2137
2138       vam->client_index_invalid = 1;
2139
2140       /* Note: this closes memfd.fd */
2141       retval = memfd_slave_init (&memfd);
2142       if (retval)
2143         clib_warning ("WARNING: segment map returned %d", retval);
2144
2145       /* Pivot to the memory client segment that vpp just created */
2146
2147       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2148
2149       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2150
2151       vl_client_install_client_message_handlers ();
2152
2153       vl_client_connect_to_vlib_no_map ("pvt",
2154                                         "vpp_api_test(p)",
2155                                         32 /* input_queue_length */ );
2156       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2157
2158       vl_socket_client_enable_disable (&vam->socket_client_main,
2159                                        0 /* disable socket */ );
2160     }
2161
2162 out:
2163   if (vam->async_mode)
2164     {
2165       vam->async_errors += (retval < 0);
2166     }
2167   else
2168     {
2169       vam->retval = retval;
2170       vam->result_ready = 1;
2171     }
2172 #endif
2173 }
2174
2175 static void vl_api_memfd_segment_create_reply_t_handler_json
2176   (vl_api_memfd_segment_create_reply_t * mp)
2177 {
2178   clib_warning ("no");
2179 }
2180
2181 static void vl_api_dns_resolve_name_reply_t_handler
2182   (vl_api_dns_resolve_name_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->result_ready = 1;
2194
2195       if (retval == 0)
2196         {
2197           if (mp->ip4_set)
2198             clib_warning ("ip4 address %U", format_ip4_address,
2199                           (ip4_address_t *) mp->ip4_address);
2200           if (mp->ip6_set)
2201             clib_warning ("ip6 address %U", format_ip6_address,
2202                           (ip6_address_t *) mp->ip6_address);
2203         }
2204       else
2205         clib_warning ("retval %d", retval);
2206     }
2207 }
2208
2209 static void vl_api_dns_resolve_name_reply_t_handler_json
2210   (vl_api_dns_resolve_name_reply_t * mp)
2211 {
2212   clib_warning ("not implemented");
2213 }
2214
2215 static void vl_api_dns_resolve_ip_reply_t_handler
2216   (vl_api_dns_resolve_ip_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->result_ready = 1;
2228
2229       if (retval == 0)
2230         {
2231           clib_warning ("canonical name %s", mp->name);
2232         }
2233       else
2234         clib_warning ("retval %d", retval);
2235     }
2236 }
2237
2238 static void vl_api_dns_resolve_ip_reply_t_handler_json
2239   (vl_api_dns_resolve_ip_reply_t * mp)
2240 {
2241   clib_warning ("not implemented");
2242 }
2243
2244
2245 static void vl_api_ip_address_details_t_handler
2246   (vl_api_ip_address_details_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   static ip_address_details_t empty_ip_address_details = { {0} };
2250   ip_address_details_t *address = NULL;
2251   ip_details_t *current_ip_details = NULL;
2252   ip_details_t *details = NULL;
2253
2254   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2255
2256   if (!details || vam->current_sw_if_index >= vec_len (details)
2257       || !details[vam->current_sw_if_index].present)
2258     {
2259       errmsg ("ip address details arrived but not stored");
2260       errmsg ("ip_dump should be called first");
2261       return;
2262     }
2263
2264   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2265
2266 #define addresses (current_ip_details->addr)
2267
2268   vec_validate_init_empty (addresses, vec_len (addresses),
2269                            empty_ip_address_details);
2270
2271   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2272
2273   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2274   address->prefix_length = mp->prefix_length;
2275 #undef addresses
2276 }
2277
2278 static void vl_api_ip_address_details_t_handler_json
2279   (vl_api_ip_address_details_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t *node = NULL;
2283   struct in6_addr ip6;
2284   struct in_addr ip4;
2285
2286   if (VAT_JSON_ARRAY != vam->json_tree.type)
2287     {
2288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2289       vat_json_init_array (&vam->json_tree);
2290     }
2291   node = vat_json_array_add (&vam->json_tree);
2292
2293   vat_json_init_object (node);
2294   if (vam->is_ipv6)
2295     {
2296       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2297       vat_json_object_add_ip6 (node, "ip", ip6);
2298     }
2299   else
2300     {
2301       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2302       vat_json_object_add_ip4 (node, "ip", ip4);
2303     }
2304   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2305 }
2306
2307 static void
2308 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   static ip_details_t empty_ip_details = { 0 };
2312   ip_details_t *ip = NULL;
2313   u32 sw_if_index = ~0;
2314
2315   sw_if_index = ntohl (mp->sw_if_index);
2316
2317   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2318                            sw_if_index, empty_ip_details);
2319
2320   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2321                          sw_if_index);
2322
2323   ip->present = 1;
2324 }
2325
2326 static void
2327 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330
2331   if (VAT_JSON_ARRAY != vam->json_tree.type)
2332     {
2333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2334       vat_json_init_array (&vam->json_tree);
2335     }
2336   vat_json_array_add_uint (&vam->json_tree,
2337                            clib_net_to_host_u32 (mp->sw_if_index));
2338 }
2339
2340 static void vl_api_map_domain_details_t_handler_json
2341   (vl_api_map_domain_details_t * mp)
2342 {
2343   vat_json_node_t *node = NULL;
2344   vat_main_t *vam = &vat_main;
2345   struct in6_addr ip6;
2346   struct in_addr ip4;
2347
2348   if (VAT_JSON_ARRAY != vam->json_tree.type)
2349     {
2350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2351       vat_json_init_array (&vam->json_tree);
2352     }
2353
2354   node = vat_json_array_add (&vam->json_tree);
2355   vat_json_init_object (node);
2356
2357   vat_json_object_add_uint (node, "domain_index",
2358                             clib_net_to_host_u32 (mp->domain_index));
2359   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2360   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2361   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2362   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2363   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2364   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2365   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2366   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2367   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2368   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2369   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2370   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2371   vat_json_object_add_uint (node, "flags", mp->flags);
2372   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2373   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2374 }
2375
2376 static void vl_api_map_domain_details_t_handler
2377   (vl_api_map_domain_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380
2381   if (mp->is_translation)
2382     {
2383       print (vam->ofp,
2384              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2385              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2386              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2387              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2388              clib_net_to_host_u32 (mp->domain_index));
2389     }
2390   else
2391     {
2392       print (vam->ofp,
2393              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2394              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2395              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2396              format_ip6_address, mp->ip6_src,
2397              clib_net_to_host_u32 (mp->domain_index));
2398     }
2399   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2400          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2401          mp->is_translation ? "map-t" : "");
2402 }
2403
2404 static void vl_api_map_rule_details_t_handler_json
2405   (vl_api_map_rule_details_t * mp)
2406 {
2407   struct in6_addr ip6;
2408   vat_json_node_t *node = NULL;
2409   vat_main_t *vam = &vat_main;
2410
2411   if (VAT_JSON_ARRAY != vam->json_tree.type)
2412     {
2413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2414       vat_json_init_array (&vam->json_tree);
2415     }
2416
2417   node = vat_json_array_add (&vam->json_tree);
2418   vat_json_init_object (node);
2419
2420   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2421   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2422   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2423 }
2424
2425 static void
2426 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2430          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2431 }
2432
2433 static void
2434 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2435 {
2436   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2437           "router_addr %U host_mac %U",
2438           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2439           format_ip4_address, &mp->host_address,
2440           format_ip4_address, &mp->router_address,
2441           format_ethernet_address, mp->host_mac);
2442 }
2443
2444 static void vl_api_dhcp_compl_event_t_handler_json
2445   (vl_api_dhcp_compl_event_t * mp)
2446 {
2447   /* JSON output not supported */
2448 }
2449
2450 static void
2451 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2452                               u32 counter)
2453 {
2454   vat_main_t *vam = &vat_main;
2455   static u64 default_counter = 0;
2456
2457   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2458                            NULL);
2459   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2460                            sw_if_index, default_counter);
2461   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2462 }
2463
2464 static void
2465 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2466                                 interface_counter_t counter)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   static interface_counter_t default_counter = { 0, };
2470
2471   vec_validate_init_empty (vam->combined_interface_counters,
2472                            vnet_counter_type, NULL);
2473   vec_validate_init_empty (vam->combined_interface_counters
2474                            [vnet_counter_type], sw_if_index, default_counter);
2475   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2476 }
2477
2478 static void vl_api_vnet_interface_simple_counters_t_handler
2479   (vl_api_vnet_interface_simple_counters_t * mp)
2480 {
2481   /* not supported */
2482 }
2483
2484 static void vl_api_vnet_interface_combined_counters_t_handler
2485   (vl_api_vnet_interface_combined_counters_t * mp)
2486 {
2487   /* not supported */
2488 }
2489
2490 static void vl_api_vnet_interface_simple_counters_t_handler_json
2491   (vl_api_vnet_interface_simple_counters_t * mp)
2492 {
2493   u64 *v_packets;
2494   u64 packets;
2495   u32 count;
2496   u32 first_sw_if_index;
2497   int i;
2498
2499   count = ntohl (mp->count);
2500   first_sw_if_index = ntohl (mp->first_sw_if_index);
2501
2502   v_packets = (u64 *) & mp->data;
2503   for (i = 0; i < count; i++)
2504     {
2505       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2506       set_simple_interface_counter (mp->vnet_counter_type,
2507                                     first_sw_if_index + i, packets);
2508       v_packets++;
2509     }
2510 }
2511
2512 static void vl_api_vnet_interface_combined_counters_t_handler_json
2513   (vl_api_vnet_interface_combined_counters_t * mp)
2514 {
2515   interface_counter_t counter;
2516   vlib_counter_t *v;
2517   u32 first_sw_if_index;
2518   int i;
2519   u32 count;
2520
2521   count = ntohl (mp->count);
2522   first_sw_if_index = ntohl (mp->first_sw_if_index);
2523
2524   v = (vlib_counter_t *) & mp->data;
2525   for (i = 0; i < count; i++)
2526     {
2527       counter.packets =
2528         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2529       counter.bytes =
2530         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2531       set_combined_interface_counter (mp->vnet_counter_type,
2532                                       first_sw_if_index + i, counter);
2533       v++;
2534     }
2535 }
2536
2537 static u32
2538 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2539 {
2540   vat_main_t *vam = &vat_main;
2541   u32 i;
2542
2543   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2544     {
2545       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2546         {
2547           return i;
2548         }
2549     }
2550   return ~0;
2551 }
2552
2553 static u32
2554 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   u32 i;
2558
2559   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2560     {
2561       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2562         {
2563           return i;
2564         }
2565     }
2566   return ~0;
2567 }
2568
2569 static void vl_api_vnet_ip4_fib_counters_t_handler
2570   (vl_api_vnet_ip4_fib_counters_t * mp)
2571 {
2572   /* not supported */
2573 }
2574
2575 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2576   (vl_api_vnet_ip4_fib_counters_t * mp)
2577 {
2578   vat_main_t *vam = &vat_main;
2579   vl_api_ip4_fib_counter_t *v;
2580   ip4_fib_counter_t *counter;
2581   struct in_addr ip4;
2582   u32 vrf_id;
2583   u32 vrf_index;
2584   u32 count;
2585   int i;
2586
2587   vrf_id = ntohl (mp->vrf_id);
2588   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2589   if (~0 == vrf_index)
2590     {
2591       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2592       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2593       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2594       vec_validate (vam->ip4_fib_counters, vrf_index);
2595       vam->ip4_fib_counters[vrf_index] = NULL;
2596     }
2597
2598   vec_free (vam->ip4_fib_counters[vrf_index]);
2599   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2600   count = ntohl (mp->count);
2601   for (i = 0; i < count; i++)
2602     {
2603       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2604       counter = &vam->ip4_fib_counters[vrf_index][i];
2605       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2606       counter->address = ip4;
2607       counter->address_length = v->address_length;
2608       counter->packets = clib_net_to_host_u64 (v->packets);
2609       counter->bytes = clib_net_to_host_u64 (v->bytes);
2610       v++;
2611     }
2612 }
2613
2614 static void vl_api_vnet_ip4_nbr_counters_t_handler
2615   (vl_api_vnet_ip4_nbr_counters_t * mp)
2616 {
2617   /* not supported */
2618 }
2619
2620 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2621   (vl_api_vnet_ip4_nbr_counters_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vl_api_ip4_nbr_counter_t *v;
2625   ip4_nbr_counter_t *counter;
2626   u32 sw_if_index;
2627   u32 count;
2628   int i;
2629
2630   sw_if_index = ntohl (mp->sw_if_index);
2631   count = ntohl (mp->count);
2632   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2633
2634   if (mp->begin)
2635     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2636
2637   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2638   for (i = 0; i < count; i++)
2639     {
2640       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2641       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2642       counter->address.s_addr = v->address;
2643       counter->packets = clib_net_to_host_u64 (v->packets);
2644       counter->bytes = clib_net_to_host_u64 (v->bytes);
2645       counter->linkt = v->link_type;
2646       v++;
2647     }
2648 }
2649
2650 static void vl_api_vnet_ip6_fib_counters_t_handler
2651   (vl_api_vnet_ip6_fib_counters_t * mp)
2652 {
2653   /* not supported */
2654 }
2655
2656 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2657   (vl_api_vnet_ip6_fib_counters_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vl_api_ip6_fib_counter_t *v;
2661   ip6_fib_counter_t *counter;
2662   struct in6_addr ip6;
2663   u32 vrf_id;
2664   u32 vrf_index;
2665   u32 count;
2666   int i;
2667
2668   vrf_id = ntohl (mp->vrf_id);
2669   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2670   if (~0 == vrf_index)
2671     {
2672       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2673       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2674       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2675       vec_validate (vam->ip6_fib_counters, vrf_index);
2676       vam->ip6_fib_counters[vrf_index] = NULL;
2677     }
2678
2679   vec_free (vam->ip6_fib_counters[vrf_index]);
2680   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2681   count = ntohl (mp->count);
2682   for (i = 0; i < count; i++)
2683     {
2684       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2685       counter = &vam->ip6_fib_counters[vrf_index][i];
2686       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2687       counter->address = ip6;
2688       counter->address_length = v->address_length;
2689       counter->packets = clib_net_to_host_u64 (v->packets);
2690       counter->bytes = clib_net_to_host_u64 (v->bytes);
2691       v++;
2692     }
2693 }
2694
2695 static void vl_api_vnet_ip6_nbr_counters_t_handler
2696   (vl_api_vnet_ip6_nbr_counters_t * mp)
2697 {
2698   /* not supported */
2699 }
2700
2701 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2702   (vl_api_vnet_ip6_nbr_counters_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vl_api_ip6_nbr_counter_t *v;
2706   ip6_nbr_counter_t *counter;
2707   struct in6_addr ip6;
2708   u32 sw_if_index;
2709   u32 count;
2710   int i;
2711
2712   sw_if_index = ntohl (mp->sw_if_index);
2713   count = ntohl (mp->count);
2714   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2715
2716   if (mp->begin)
2717     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2718
2719   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2720   for (i = 0; i < count; i++)
2721     {
2722       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2723       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2724       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2725       counter->address = ip6;
2726       counter->packets = clib_net_to_host_u64 (v->packets);
2727       counter->bytes = clib_net_to_host_u64 (v->bytes);
2728       v++;
2729     }
2730 }
2731
2732 static void vl_api_get_first_msg_id_reply_t_handler
2733   (vl_api_get_first_msg_id_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (vam->async_mode)
2739     {
2740       vam->async_errors += (retval < 0);
2741     }
2742   else
2743     {
2744       vam->retval = retval;
2745       vam->result_ready = 1;
2746     }
2747   if (retval >= 0)
2748     {
2749       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2750     }
2751 }
2752
2753 static void vl_api_get_first_msg_id_reply_t_handler_json
2754   (vl_api_get_first_msg_id_reply_t * mp)
2755 {
2756   vat_main_t *vam = &vat_main;
2757   vat_json_node_t node;
2758
2759   vat_json_init_object (&node);
2760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2761   vat_json_object_add_uint (&node, "first_msg_id",
2762                             (uint) ntohs (mp->first_msg_id));
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static void vl_api_get_node_graph_reply_t_handler
2772   (vl_api_get_node_graph_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   api_main_t *am = &api_main;
2776   i32 retval = ntohl (mp->retval);
2777   u8 *pvt_copy, *reply;
2778   void *oldheap;
2779   vlib_node_t *node;
2780   int i;
2781
2782   if (vam->async_mode)
2783     {
2784       vam->async_errors += (retval < 0);
2785     }
2786   else
2787     {
2788       vam->retval = retval;
2789       vam->result_ready = 1;
2790     }
2791
2792   /* "Should never happen..." */
2793   if (retval != 0)
2794     return;
2795
2796   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2797   pvt_copy = vec_dup (reply);
2798
2799   /* Toss the shared-memory original... */
2800   pthread_mutex_lock (&am->vlib_rp->mutex);
2801   oldheap = svm_push_data_heap (am->vlib_rp);
2802
2803   vec_free (reply);
2804
2805   svm_pop_heap (oldheap);
2806   pthread_mutex_unlock (&am->vlib_rp->mutex);
2807
2808   if (vam->graph_nodes)
2809     {
2810       hash_free (vam->graph_node_index_by_name);
2811
2812       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2813         {
2814           node = vam->graph_nodes[i];
2815           vec_free (node->name);
2816           vec_free (node->next_nodes);
2817           vec_free (node);
2818         }
2819       vec_free (vam->graph_nodes);
2820     }
2821
2822   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2823   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2824   vec_free (pvt_copy);
2825
2826   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2827     {
2828       node = vam->graph_nodes[i];
2829       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2830     }
2831 }
2832
2833 static void vl_api_get_node_graph_reply_t_handler_json
2834   (vl_api_get_node_graph_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   api_main_t *am = &api_main;
2838   void *oldheap;
2839   vat_json_node_t node;
2840   u8 *reply;
2841
2842   /* $$$$ make this real? */
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2846
2847   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2848
2849   /* Toss the shared-memory original... */
2850   pthread_mutex_lock (&am->vlib_rp->mutex);
2851   oldheap = svm_push_data_heap (am->vlib_rp);
2852
2853   vec_free (reply);
2854
2855   svm_pop_heap (oldheap);
2856   pthread_mutex_unlock (&am->vlib_rp->mutex);
2857
2858   vat_json_print (vam->ofp, &node);
2859   vat_json_free (&node);
2860
2861   vam->retval = ntohl (mp->retval);
2862   vam->result_ready = 1;
2863 }
2864
2865 static void
2866 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2867 {
2868   vat_main_t *vam = &vat_main;
2869   u8 *s = 0;
2870
2871   if (mp->local)
2872     {
2873       s = format (s, "%=16d%=16d%=16d",
2874                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2875     }
2876   else
2877     {
2878       s = format (s, "%=16U%=16d%=16d",
2879                   mp->is_ipv6 ? format_ip6_address :
2880                   format_ip4_address,
2881                   mp->ip_address, mp->priority, mp->weight);
2882     }
2883
2884   print (vam->ofp, "%v", s);
2885   vec_free (s);
2886 }
2887
2888 static void
2889 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2890 {
2891   vat_main_t *vam = &vat_main;
2892   vat_json_node_t *node = NULL;
2893   struct in6_addr ip6;
2894   struct in_addr ip4;
2895
2896   if (VAT_JSON_ARRAY != vam->json_tree.type)
2897     {
2898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2899       vat_json_init_array (&vam->json_tree);
2900     }
2901   node = vat_json_array_add (&vam->json_tree);
2902   vat_json_init_object (node);
2903
2904   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2905   vat_json_object_add_uint (node, "priority", mp->priority);
2906   vat_json_object_add_uint (node, "weight", mp->weight);
2907
2908   if (mp->local)
2909     vat_json_object_add_uint (node, "sw_if_index",
2910                               clib_net_to_host_u32 (mp->sw_if_index));
2911   else
2912     {
2913       if (mp->is_ipv6)
2914         {
2915           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2916           vat_json_object_add_ip6 (node, "address", ip6);
2917         }
2918       else
2919         {
2920           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2921           vat_json_object_add_ip4 (node, "address", ip4);
2922         }
2923     }
2924 }
2925
2926 static void
2927 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2928                                           mp)
2929 {
2930   vat_main_t *vam = &vat_main;
2931   u8 *ls_name = 0;
2932
2933   ls_name = format (0, "%s", mp->ls_name);
2934
2935   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2936          ls_name);
2937   vec_free (ls_name);
2938 }
2939
2940 static void
2941   vl_api_one_locator_set_details_t_handler_json
2942   (vl_api_one_locator_set_details_t * mp)
2943 {
2944   vat_main_t *vam = &vat_main;
2945   vat_json_node_t *node = 0;
2946   u8 *ls_name = 0;
2947
2948   ls_name = format (0, "%s", mp->ls_name);
2949   vec_add1 (ls_name, 0);
2950
2951   if (VAT_JSON_ARRAY != vam->json_tree.type)
2952     {
2953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2954       vat_json_init_array (&vam->json_tree);
2955     }
2956   node = vat_json_array_add (&vam->json_tree);
2957
2958   vat_json_init_object (node);
2959   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2960   vat_json_object_add_uint (node, "ls_index",
2961                             clib_net_to_host_u32 (mp->ls_index));
2962   vec_free (ls_name);
2963 }
2964
2965 typedef struct
2966 {
2967   u32 spi;
2968   u8 si;
2969 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2970
2971 uword
2972 unformat_nsh_address (unformat_input_t * input, va_list * args)
2973 {
2974   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2975   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2976 }
2977
2978 u8 *
2979 format_nsh_address_vat (u8 * s, va_list * args)
2980 {
2981   nsh_t *a = va_arg (*args, nsh_t *);
2982   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2983 }
2984
2985 static u8 *
2986 format_lisp_flat_eid (u8 * s, va_list * args)
2987 {
2988   u32 type = va_arg (*args, u32);
2989   u8 *eid = va_arg (*args, u8 *);
2990   u32 eid_len = va_arg (*args, u32);
2991
2992   switch (type)
2993     {
2994     case 0:
2995       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2996     case 1:
2997       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2998     case 2:
2999       return format (s, "%U", format_ethernet_address, eid);
3000     case 3:
3001       return format (s, "%U", format_nsh_address_vat, eid);
3002     }
3003   return 0;
3004 }
3005
3006 static u8 *
3007 format_lisp_eid_vat (u8 * s, va_list * args)
3008 {
3009   u32 type = va_arg (*args, u32);
3010   u8 *eid = va_arg (*args, u8 *);
3011   u32 eid_len = va_arg (*args, u32);
3012   u8 *seid = va_arg (*args, u8 *);
3013   u32 seid_len = va_arg (*args, u32);
3014   u32 is_src_dst = va_arg (*args, u32);
3015
3016   if (is_src_dst)
3017     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3018
3019   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3020
3021   return s;
3022 }
3023
3024 static void
3025 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u8 *s = 0, *eid = 0;
3029
3030   if (~0 == mp->locator_set_index)
3031     s = format (0, "action: %d", mp->action);
3032   else
3033     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3034
3035   eid = format (0, "%U", format_lisp_eid_vat,
3036                 mp->eid_type,
3037                 mp->eid,
3038                 mp->eid_prefix_len,
3039                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3040   vec_add1 (eid, 0);
3041
3042   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3043          clib_net_to_host_u32 (mp->vni),
3044          eid,
3045          mp->is_local ? "local" : "remote",
3046          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3047          clib_net_to_host_u16 (mp->key_id), mp->key);
3048
3049   vec_free (s);
3050   vec_free (eid);
3051 }
3052
3053 static void
3054 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3055                                              * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058   vat_json_node_t *node = 0;
3059   u8 *eid = 0;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   if (~0 == mp->locator_set_index)
3070     vat_json_object_add_uint (node, "action", mp->action);
3071   else
3072     vat_json_object_add_uint (node, "locator_set_index",
3073                               clib_net_to_host_u32 (mp->locator_set_index));
3074
3075   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3076   if (mp->eid_type == 3)
3077     {
3078       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3079       vat_json_init_object (nsh_json);
3080       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3081       vat_json_object_add_uint (nsh_json, "spi",
3082                                 clib_net_to_host_u32 (nsh->spi));
3083       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3084     }
3085   else
3086     {
3087       eid = format (0, "%U", format_lisp_eid_vat,
3088                     mp->eid_type,
3089                     mp->eid,
3090                     mp->eid_prefix_len,
3091                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3092       vec_add1 (eid, 0);
3093       vat_json_object_add_string_copy (node, "eid", eid);
3094       vec_free (eid);
3095     }
3096   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3097   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3098   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3099
3100   if (mp->key_id)
3101     {
3102       vat_json_object_add_uint (node, "key_id",
3103                                 clib_net_to_host_u16 (mp->key_id));
3104       vat_json_object_add_string_copy (node, "key", mp->key);
3105     }
3106 }
3107
3108 static void
3109 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *seid = 0, *deid = 0;
3113   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3114
3115   deid = format (0, "%U", format_lisp_eid_vat,
3116                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3117
3118   seid = format (0, "%U", format_lisp_eid_vat,
3119                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3120
3121   vec_add1 (deid, 0);
3122   vec_add1 (seid, 0);
3123
3124   if (mp->is_ip4)
3125     format_ip_address_fcn = format_ip4_address;
3126   else
3127     format_ip_address_fcn = format_ip6_address;
3128
3129
3130   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3131          clib_net_to_host_u32 (mp->vni),
3132          seid, deid,
3133          format_ip_address_fcn, mp->lloc,
3134          format_ip_address_fcn, mp->rloc,
3135          clib_net_to_host_u32 (mp->pkt_count),
3136          clib_net_to_host_u32 (mp->bytes));
3137
3138   vec_free (deid);
3139   vec_free (seid);
3140 }
3141
3142 static void
3143 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3144 {
3145   struct in6_addr ip6;
3146   struct in_addr ip4;
3147   vat_main_t *vam = &vat_main;
3148   vat_json_node_t *node = 0;
3149   u8 *deid = 0, *seid = 0;
3150
3151   if (VAT_JSON_ARRAY != vam->json_tree.type)
3152     {
3153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3154       vat_json_init_array (&vam->json_tree);
3155     }
3156   node = vat_json_array_add (&vam->json_tree);
3157
3158   vat_json_init_object (node);
3159   deid = format (0, "%U", format_lisp_eid_vat,
3160                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3161
3162   seid = format (0, "%U", format_lisp_eid_vat,
3163                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3164
3165   vec_add1 (deid, 0);
3166   vec_add1 (seid, 0);
3167
3168   vat_json_object_add_string_copy (node, "seid", seid);
3169   vat_json_object_add_string_copy (node, "deid", deid);
3170   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3171
3172   if (mp->is_ip4)
3173     {
3174       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3175       vat_json_object_add_ip4 (node, "lloc", ip4);
3176       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3177       vat_json_object_add_ip4 (node, "rloc", ip4);
3178     }
3179   else
3180     {
3181       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3182       vat_json_object_add_ip6 (node, "lloc", ip6);
3183       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3184       vat_json_object_add_ip6 (node, "rloc", ip6);
3185     }
3186   vat_json_object_add_uint (node, "pkt_count",
3187                             clib_net_to_host_u32 (mp->pkt_count));
3188   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3189
3190   vec_free (deid);
3191   vec_free (seid);
3192 }
3193
3194 static void
3195   vl_api_one_eid_table_map_details_t_handler
3196   (vl_api_one_eid_table_map_details_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199
3200   u8 *line = format (0, "%=10d%=10d",
3201                      clib_net_to_host_u32 (mp->vni),
3202                      clib_net_to_host_u32 (mp->dp_table));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_map_details_t_handler_json
3209   (vl_api_one_eid_table_map_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node = NULL;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220   vat_json_init_object (node);
3221   vat_json_object_add_uint (node, "dp_table",
3222                             clib_net_to_host_u32 (mp->dp_table));
3223   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3224 }
3225
3226 static void
3227   vl_api_one_eid_table_vni_details_t_handler
3228   (vl_api_one_eid_table_vni_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3233   print (vam->ofp, "%v", line);
3234   vec_free (line);
3235 }
3236
3237 static void
3238   vl_api_one_eid_table_vni_details_t_handler_json
3239   (vl_api_one_eid_table_vni_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   vat_json_node_t *node = NULL;
3243
3244   if (VAT_JSON_ARRAY != vam->json_tree.type)
3245     {
3246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3247       vat_json_init_array (&vam->json_tree);
3248     }
3249   node = vat_json_array_add (&vam->json_tree);
3250   vat_json_init_object (node);
3251   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3252 }
3253
3254 static void
3255   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3256   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   int retval = clib_net_to_host_u32 (mp->retval);
3260
3261   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3262   print (vam->ofp, "fallback threshold value: %d", mp->value);
3263
3264   vam->retval = retval;
3265   vam->result_ready = 1;
3266 }
3267
3268 static void
3269   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3270   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3271 {
3272   vat_main_t *vam = &vat_main;
3273   vat_json_node_t _node, *node = &_node;
3274   int retval = clib_net_to_host_u32 (mp->retval);
3275
3276   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3277   vat_json_init_object (node);
3278   vat_json_object_add_uint (node, "value", mp->value);
3279
3280   vat_json_print (vam->ofp, node);
3281   vat_json_free (node);
3282
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_show_one_map_register_state_reply_t_handler
3289   (vl_api_show_one_map_register_state_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3295
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_map_register_state_reply_t_handler_json
3302   (vl_api_show_one_map_register_state_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3309
3310   vat_json_init_object (node);
3311   vat_json_object_add_string_copy (node, "state", s);
3312
3313   vat_json_print (vam->ofp, node);
3314   vat_json_free (node);
3315
3316   vam->retval = retval;
3317   vam->result_ready = 1;
3318   vec_free (s);
3319 }
3320
3321 static void
3322   vl_api_show_one_rloc_probe_state_reply_t_handler
3323   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   int retval = clib_net_to_host_u32 (mp->retval);
3327
3328   if (retval)
3329     goto end;
3330
3331   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3332 end:
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3339   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3346   vat_json_init_object (node);
3347   vat_json_object_add_string_copy (node, "state", s);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354   vec_free (s);
3355 }
3356
3357 static void
3358   vl_api_show_one_stats_enable_disable_reply_t_handler
3359   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3360 {
3361   vat_main_t *vam = &vat_main;
3362   int retval = clib_net_to_host_u32 (mp->retval);
3363
3364   if (retval)
3365     goto end;
3366
3367   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3368 end:
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371 }
3372
3373 static void
3374   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3375   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t _node, *node = &_node;
3379   int retval = clib_net_to_host_u32 (mp->retval);
3380
3381   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3382   vat_json_init_object (node);
3383   vat_json_object_add_string_copy (node, "state", s);
3384
3385   vat_json_print (vam->ofp, node);
3386   vat_json_free (node);
3387
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390   vec_free (s);
3391 }
3392
3393 static void
3394 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3395 {
3396   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3397   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3398   e->vni = clib_net_to_host_u32 (e->vni);
3399 }
3400
3401 static void
3402   gpe_fwd_entries_get_reply_t_net_to_host
3403   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3404 {
3405   u32 i;
3406
3407   mp->count = clib_net_to_host_u32 (mp->count);
3408   for (i = 0; i < mp->count; i++)
3409     {
3410       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3411     }
3412 }
3413
3414 static u8 *
3415 format_gpe_encap_mode (u8 * s, va_list * args)
3416 {
3417   u32 mode = va_arg (*args, u32);
3418
3419   switch (mode)
3420     {
3421     case 0:
3422       return format (s, "lisp");
3423     case 1:
3424       return format (s, "vxlan");
3425     }
3426   return 0;
3427 }
3428
3429 static void
3430   vl_api_gpe_get_encap_mode_reply_t_handler
3431   (vl_api_gpe_get_encap_mode_reply_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3436   vam->retval = ntohl (mp->retval);
3437   vam->result_ready = 1;
3438 }
3439
3440 static void
3441   vl_api_gpe_get_encap_mode_reply_t_handler_json
3442   (vl_api_gpe_get_encap_mode_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   vat_json_node_t node;
3446
3447   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3448   vec_add1 (encap_mode, 0);
3449
3450   vat_json_init_object (&node);
3451   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3452
3453   vec_free (encap_mode);
3454   vat_json_print (vam->ofp, &node);
3455   vat_json_free (&node);
3456
3457   vam->retval = ntohl (mp->retval);
3458   vam->result_ready = 1;
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entry_path_details_t_handler
3463   (vl_api_gpe_fwd_entry_path_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3467
3468   if (mp->lcl_loc.is_ip4)
3469     format_ip_address_fcn = format_ip4_address;
3470   else
3471     format_ip_address_fcn = format_ip6_address;
3472
3473   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3474          format_ip_address_fcn, &mp->lcl_loc,
3475          format_ip_address_fcn, &mp->rmt_loc);
3476 }
3477
3478 static void
3479 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3480 {
3481   struct in6_addr ip6;
3482   struct in_addr ip4;
3483
3484   if (loc->is_ip4)
3485     {
3486       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3487       vat_json_object_add_ip4 (n, "address", ip4);
3488     }
3489   else
3490     {
3491       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3492       vat_json_object_add_ip6 (n, "address", ip6);
3493     }
3494   vat_json_object_add_uint (n, "weight", loc->weight);
3495 }
3496
3497 static void
3498   vl_api_gpe_fwd_entry_path_details_t_handler_json
3499   (vl_api_gpe_fwd_entry_path_details_t * mp)
3500 {
3501   vat_main_t *vam = &vat_main;
3502   vat_json_node_t *node = NULL;
3503   vat_json_node_t *loc_node;
3504
3505   if (VAT_JSON_ARRAY != vam->json_tree.type)
3506     {
3507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3508       vat_json_init_array (&vam->json_tree);
3509     }
3510   node = vat_json_array_add (&vam->json_tree);
3511   vat_json_init_object (node);
3512
3513   loc_node = vat_json_object_add (node, "local_locator");
3514   vat_json_init_object (loc_node);
3515   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3516
3517   loc_node = vat_json_object_add (node, "remote_locator");
3518   vat_json_init_object (loc_node);
3519   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3520 }
3521
3522 static void
3523   vl_api_gpe_fwd_entries_get_reply_t_handler
3524   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   u32 i;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_fwd_entry_t *e;
3530
3531   if (retval)
3532     goto end;
3533
3534   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3535
3536   for (i = 0; i < mp->count; i++)
3537     {
3538       e = &mp->entries[i];
3539       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3540              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3541              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3542     }
3543
3544 end:
3545   vam->retval = retval;
3546   vam->result_ready = 1;
3547 }
3548
3549 static void
3550   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3551   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3552 {
3553   u8 *s = 0;
3554   vat_main_t *vam = &vat_main;
3555   vat_json_node_t *e = 0, root;
3556   u32 i;
3557   int retval = clib_net_to_host_u32 (mp->retval);
3558   vl_api_gpe_fwd_entry_t *fwd;
3559
3560   if (retval)
3561     goto end;
3562
3563   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3564   vat_json_init_array (&root);
3565
3566   for (i = 0; i < mp->count; i++)
3567     {
3568       e = vat_json_array_add (&root);
3569       fwd = &mp->entries[i];
3570
3571       vat_json_init_object (e);
3572       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3573       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3574       vat_json_object_add_int (e, "vni", fwd->vni);
3575       vat_json_object_add_int (e, "action", fwd->action);
3576
3577       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3578                   fwd->leid_prefix_len);
3579       vec_add1 (s, 0);
3580       vat_json_object_add_string_copy (e, "leid", s);
3581       vec_free (s);
3582
3583       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3584                   fwd->reid_prefix_len);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "reid", s);
3587       vec_free (s);
3588     }
3589
3590   vat_json_print (vam->ofp, &root);
3591   vat_json_free (&root);
3592
3593 end:
3594   vam->retval = retval;
3595   vam->result_ready = 1;
3596 }
3597
3598 static void
3599   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3600   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3601 {
3602   vat_main_t *vam = &vat_main;
3603   u32 i, n;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605   vl_api_gpe_native_fwd_rpath_t *r;
3606
3607   if (retval)
3608     goto end;
3609
3610   n = clib_net_to_host_u32 (mp->count);
3611
3612   for (i = 0; i < n; i++)
3613     {
3614       r = &mp->entries[i];
3615       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3616              clib_net_to_host_u32 (r->fib_index),
3617              clib_net_to_host_u32 (r->nh_sw_if_index),
3618              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3619     }
3620
3621 end:
3622   vam->retval = retval;
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3628   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t root, *e;
3632   u32 i, n;
3633   int retval = clib_net_to_host_u32 (mp->retval);
3634   vl_api_gpe_native_fwd_rpath_t *r;
3635   u8 *s;
3636
3637   if (retval)
3638     goto end;
3639
3640   n = clib_net_to_host_u32 (mp->count);
3641   vat_json_init_array (&root);
3642
3643   for (i = 0; i < n; i++)
3644     {
3645       e = vat_json_array_add (&root);
3646       vat_json_init_object (e);
3647       r = &mp->entries[i];
3648       s =
3649         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3650                 r->nh_addr);
3651       vec_add1 (s, 0);
3652       vat_json_object_add_string_copy (e, "ip4", s);
3653       vec_free (s);
3654
3655       vat_json_object_add_uint (e, "fib_index",
3656                                 clib_net_to_host_u32 (r->fib_index));
3657       vat_json_object_add_uint (e, "nh_sw_if_index",
3658                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3659     }
3660
3661   vat_json_print (vam->ofp, &root);
3662   vat_json_free (&root);
3663
3664 end:
3665   vam->retval = retval;
3666   vam->result_ready = 1;
3667 }
3668
3669 static void
3670   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3671   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3672 {
3673   vat_main_t *vam = &vat_main;
3674   u32 i, n;
3675   int retval = clib_net_to_host_u32 (mp->retval);
3676
3677   if (retval)
3678     goto end;
3679
3680   n = clib_net_to_host_u32 (mp->count);
3681
3682   for (i = 0; i < n; i++)
3683     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3692   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   vat_json_node_t root;
3696   u32 i, n;
3697   int retval = clib_net_to_host_u32 (mp->retval);
3698
3699   if (retval)
3700     goto end;
3701
3702   n = clib_net_to_host_u32 (mp->count);
3703   vat_json_init_array (&root);
3704
3705   for (i = 0; i < n; i++)
3706     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3707
3708   vat_json_print (vam->ofp, &root);
3709   vat_json_free (&root);
3710
3711 end:
3712   vam->retval = retval;
3713   vam->result_ready = 1;
3714 }
3715
3716 static void
3717   vl_api_one_ndp_entries_get_reply_t_handler
3718   (vl_api_one_ndp_entries_get_reply_t * mp)
3719 {
3720   vat_main_t *vam = &vat_main;
3721   u32 i, n;
3722   int retval = clib_net_to_host_u32 (mp->retval);
3723
3724   if (retval)
3725     goto end;
3726
3727   n = clib_net_to_host_u32 (mp->count);
3728
3729   for (i = 0; i < n; i++)
3730     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3731            format_ethernet_address, mp->entries[i].mac);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_one_ndp_entries_get_reply_t_handler_json
3740   (vl_api_one_ndp_entries_get_reply_t * mp)
3741 {
3742   u8 *s = 0;
3743   vat_main_t *vam = &vat_main;
3744   vat_json_node_t *e = 0, root;
3745   u32 i, n;
3746   int retval = clib_net_to_host_u32 (mp->retval);
3747   vl_api_one_ndp_entry_t *arp_entry;
3748
3749   if (retval)
3750     goto end;
3751
3752   n = clib_net_to_host_u32 (mp->count);
3753   vat_json_init_array (&root);
3754
3755   for (i = 0; i < n; i++)
3756     {
3757       e = vat_json_array_add (&root);
3758       arp_entry = &mp->entries[i];
3759
3760       vat_json_init_object (e);
3761       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3762       vec_add1 (s, 0);
3763
3764       vat_json_object_add_string_copy (e, "mac", s);
3765       vec_free (s);
3766
3767       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3768       vec_add1 (s, 0);
3769       vat_json_object_add_string_copy (e, "ip6", s);
3770       vec_free (s);
3771     }
3772
3773   vat_json_print (vam->ofp, &root);
3774   vat_json_free (&root);
3775
3776 end:
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_one_l2_arp_entries_get_reply_t_handler
3783   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   u32 i, n;
3787   int retval = clib_net_to_host_u32 (mp->retval);
3788
3789   if (retval)
3790     goto end;
3791
3792   n = clib_net_to_host_u32 (mp->count);
3793
3794   for (i = 0; i < n; i++)
3795     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3796            format_ethernet_address, mp->entries[i].mac);
3797
3798 end:
3799   vam->retval = retval;
3800   vam->result_ready = 1;
3801 }
3802
3803 static void
3804   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3805   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3806 {
3807   u8 *s = 0;
3808   vat_main_t *vam = &vat_main;
3809   vat_json_node_t *e = 0, root;
3810   u32 i, n;
3811   int retval = clib_net_to_host_u32 (mp->retval);
3812   vl_api_one_l2_arp_entry_t *arp_entry;
3813
3814   if (retval)
3815     goto end;
3816
3817   n = clib_net_to_host_u32 (mp->count);
3818   vat_json_init_array (&root);
3819
3820   for (i = 0; i < n; i++)
3821     {
3822       e = vat_json_array_add (&root);
3823       arp_entry = &mp->entries[i];
3824
3825       vat_json_init_object (e);
3826       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3827       vec_add1 (s, 0);
3828
3829       vat_json_object_add_string_copy (e, "mac", s);
3830       vec_free (s);
3831
3832       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3833       vec_add1 (s, 0);
3834       vat_json_object_add_string_copy (e, "ip4", s);
3835       vec_free (s);
3836     }
3837
3838   vat_json_print (vam->ofp, &root);
3839   vat_json_free (&root);
3840
3841 end:
3842   vam->retval = retval;
3843   vam->result_ready = 1;
3844 }
3845
3846 static void
3847 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   u32 i, n;
3851   int retval = clib_net_to_host_u32 (mp->retval);
3852
3853   if (retval)
3854     goto end;
3855
3856   n = clib_net_to_host_u32 (mp->count);
3857
3858   for (i = 0; i < n; i++)
3859     {
3860       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3861     }
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_ndp_bd_get_reply_t_handler_json
3870   (vl_api_one_ndp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   vat_json_node_t root;
3874   u32 i, n;
3875   int retval = clib_net_to_host_u32 (mp->retval);
3876
3877   if (retval)
3878     goto end;
3879
3880   n = clib_net_to_host_u32 (mp->count);
3881   vat_json_init_array (&root);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       vat_json_array_add_uint (&root,
3886                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3887     }
3888
3889   vat_json_print (vam->ofp, &root);
3890   vat_json_free (&root);
3891
3892 end:
3893   vam->retval = retval;
3894   vam->result_ready = 1;
3895 }
3896
3897 static void
3898   vl_api_one_l2_arp_bd_get_reply_t_handler
3899   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3900 {
3901   vat_main_t *vam = &vat_main;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904
3905   if (retval)
3906     goto end;
3907
3908   n = clib_net_to_host_u32 (mp->count);
3909
3910   for (i = 0; i < n; i++)
3911     {
3912       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3913     }
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3922   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   vat_json_node_t root;
3926   u32 i, n;
3927   int retval = clib_net_to_host_u32 (mp->retval);
3928
3929   if (retval)
3930     goto end;
3931
3932   n = clib_net_to_host_u32 (mp->count);
3933   vat_json_init_array (&root);
3934
3935   for (i = 0; i < n; i++)
3936     {
3937       vat_json_array_add_uint (&root,
3938                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3939     }
3940
3941   vat_json_print (vam->ofp, &root);
3942   vat_json_free (&root);
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_one_adjacencies_get_reply_t_handler
3951   (vl_api_one_adjacencies_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956   vl_api_one_adjacency_t *a;
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962
3963   for (i = 0; i < n; i++)
3964     {
3965       a = &mp->adjacencies[i];
3966       print (vam->ofp, "%U %40U",
3967              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3968              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3969     }
3970
3971 end:
3972   vam->retval = retval;
3973   vam->result_ready = 1;
3974 }
3975
3976 static void
3977   vl_api_one_adjacencies_get_reply_t_handler_json
3978   (vl_api_one_adjacencies_get_reply_t * mp)
3979 {
3980   u8 *s = 0;
3981   vat_main_t *vam = &vat_main;
3982   vat_json_node_t *e = 0, root;
3983   u32 i, n;
3984   int retval = clib_net_to_host_u32 (mp->retval);
3985   vl_api_one_adjacency_t *a;
3986
3987   if (retval)
3988     goto end;
3989
3990   n = clib_net_to_host_u32 (mp->count);
3991   vat_json_init_array (&root);
3992
3993   for (i = 0; i < n; i++)
3994     {
3995       e = vat_json_array_add (&root);
3996       a = &mp->adjacencies[i];
3997
3998       vat_json_init_object (e);
3999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4000                   a->leid_prefix_len);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "leid", s);
4003       vec_free (s);
4004
4005       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4006                   a->reid_prefix_len);
4007       vec_add1 (s, 0);
4008       vat_json_object_add_string_copy (e, "reid", s);
4009       vec_free (s);
4010     }
4011
4012   vat_json_print (vam->ofp, &root);
4013   vat_json_free (&root);
4014
4015 end:
4016   vam->retval = retval;
4017   vam->result_ready = 1;
4018 }
4019
4020 static void
4021 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4022 {
4023   vat_main_t *vam = &vat_main;
4024
4025   print (vam->ofp, "%=20U",
4026          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4027          mp->ip_address);
4028 }
4029
4030 static void
4031   vl_api_one_map_server_details_t_handler_json
4032   (vl_api_one_map_server_details_t * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035   vat_json_node_t *node = NULL;
4036   struct in6_addr ip6;
4037   struct in_addr ip4;
4038
4039   if (VAT_JSON_ARRAY != vam->json_tree.type)
4040     {
4041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4042       vat_json_init_array (&vam->json_tree);
4043     }
4044   node = vat_json_array_add (&vam->json_tree);
4045
4046   vat_json_init_object (node);
4047   if (mp->is_ipv6)
4048     {
4049       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4050       vat_json_object_add_ip6 (node, "map-server", ip6);
4051     }
4052   else
4053     {
4054       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4055       vat_json_object_add_ip4 (node, "map-server", ip4);
4056     }
4057 }
4058
4059 static void
4060 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4061                                            * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064
4065   print (vam->ofp, "%=20U",
4066          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4067          mp->ip_address);
4068 }
4069
4070 static void
4071   vl_api_one_map_resolver_details_t_handler_json
4072   (vl_api_one_map_resolver_details_t * mp)
4073 {
4074   vat_main_t *vam = &vat_main;
4075   vat_json_node_t *node = NULL;
4076   struct in6_addr ip6;
4077   struct in_addr ip4;
4078
4079   if (VAT_JSON_ARRAY != vam->json_tree.type)
4080     {
4081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4082       vat_json_init_array (&vam->json_tree);
4083     }
4084   node = vat_json_array_add (&vam->json_tree);
4085
4086   vat_json_init_object (node);
4087   if (mp->is_ipv6)
4088     {
4089       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4090       vat_json_object_add_ip6 (node, "map resolver", ip6);
4091     }
4092   else
4093     {
4094       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4095       vat_json_object_add_ip4 (node, "map resolver", ip4);
4096     }
4097 }
4098
4099 static void
4100 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       print (vam->ofp, "feature: %s\ngpe: %s",
4108              mp->feature_status ? "enabled" : "disabled",
4109              mp->gpe_status ? "enabled" : "disabled");
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_status_reply_t_handler_json
4118   (vl_api_show_one_status_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *gpe_status = NULL;
4123   u8 *feature_status = NULL;
4124
4125   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4126   feature_status = format (0, "%s",
4127                            mp->feature_status ? "enabled" : "disabled");
4128   vec_add1 (gpe_status, 0);
4129   vec_add1 (feature_status, 0);
4130
4131   vat_json_init_object (&node);
4132   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4133   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4134
4135   vec_free (gpe_status);
4136   vec_free (feature_status);
4137
4138   vat_json_print (vam->ofp, &node);
4139   vat_json_free (&node);
4140
4141   vam->retval = ntohl (mp->retval);
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4147   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   i32 retval = ntohl (mp->retval);
4151
4152   if (retval >= 0)
4153     {
4154       print (vam->ofp, "%=20s", mp->locator_set_name);
4155     }
4156
4157   vam->retval = retval;
4158   vam->result_ready = 1;
4159 }
4160
4161 static void
4162   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4163   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4164 {
4165   vat_main_t *vam = &vat_main;
4166   vat_json_node_t *node = NULL;
4167
4168   if (VAT_JSON_ARRAY != vam->json_tree.type)
4169     {
4170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4171       vat_json_init_array (&vam->json_tree);
4172     }
4173   node = vat_json_array_add (&vam->json_tree);
4174
4175   vat_json_init_object (node);
4176   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4177
4178   vat_json_print (vam->ofp, node);
4179   vat_json_free (node);
4180
4181   vam->retval = ntohl (mp->retval);
4182   vam->result_ready = 1;
4183 }
4184
4185 static u8 *
4186 format_lisp_map_request_mode (u8 * s, va_list * args)
4187 {
4188   u32 mode = va_arg (*args, u32);
4189
4190   switch (mode)
4191     {
4192     case 0:
4193       return format (0, "dst-only");
4194     case 1:
4195       return format (0, "src-dst");
4196     }
4197   return 0;
4198 }
4199
4200 static void
4201   vl_api_show_one_map_request_mode_reply_t_handler
4202   (vl_api_show_one_map_request_mode_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   i32 retval = ntohl (mp->retval);
4206
4207   if (0 <= retval)
4208     {
4209       u32 mode = mp->mode;
4210       print (vam->ofp, "map_request_mode: %U",
4211              format_lisp_map_request_mode, mode);
4212     }
4213
4214   vam->retval = retval;
4215   vam->result_ready = 1;
4216 }
4217
4218 static void
4219   vl_api_show_one_map_request_mode_reply_t_handler_json
4220   (vl_api_show_one_map_request_mode_reply_t * mp)
4221 {
4222   vat_main_t *vam = &vat_main;
4223   vat_json_node_t node;
4224   u8 *s = 0;
4225   u32 mode;
4226
4227   mode = mp->mode;
4228   s = format (0, "%U", format_lisp_map_request_mode, mode);
4229   vec_add1 (s, 0);
4230
4231   vat_json_init_object (&node);
4232   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4233   vat_json_print (vam->ofp, &node);
4234   vat_json_free (&node);
4235
4236   vec_free (s);
4237   vam->retval = ntohl (mp->retval);
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_show_one_use_petr_reply_t_handler
4243   (vl_api_show_one_use_petr_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   i32 retval = ntohl (mp->retval);
4247
4248   if (0 <= retval)
4249     {
4250       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4251       if (mp->status)
4252         {
4253           print (vam->ofp, "Proxy-ETR address; %U",
4254                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4255                  mp->address);
4256         }
4257     }
4258
4259   vam->retval = retval;
4260   vam->result_ready = 1;
4261 }
4262
4263 static void
4264   vl_api_show_one_use_petr_reply_t_handler_json
4265   (vl_api_show_one_use_petr_reply_t * mp)
4266 {
4267   vat_main_t *vam = &vat_main;
4268   vat_json_node_t node;
4269   u8 *status = 0;
4270   struct in_addr ip4;
4271   struct in6_addr ip6;
4272
4273   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4274   vec_add1 (status, 0);
4275
4276   vat_json_init_object (&node);
4277   vat_json_object_add_string_copy (&node, "status", status);
4278   if (mp->status)
4279     {
4280       if (mp->is_ip4)
4281         {
4282           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4283           vat_json_object_add_ip6 (&node, "address", ip6);
4284         }
4285       else
4286         {
4287           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4288           vat_json_object_add_ip4 (&node, "address", ip4);
4289         }
4290     }
4291
4292   vec_free (status);
4293
4294   vat_json_print (vam->ofp, &node);
4295   vat_json_free (&node);
4296
4297   vam->retval = ntohl (mp->retval);
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_show_one_nsh_mapping_reply_t_handler
4303   (vl_api_show_one_nsh_mapping_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   i32 retval = ntohl (mp->retval);
4307
4308   if (0 <= retval)
4309     {
4310       print (vam->ofp, "%-20s%-16s",
4311              mp->is_set ? "set" : "not-set",
4312              mp->is_set ? (char *) mp->locator_set_name : "");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_nsh_mapping_reply_t_handler_json
4321   (vl_api_show_one_nsh_mapping_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_set ? "yes" : "no");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "is_set", status);
4332   if (mp->is_set)
4333     {
4334       vat_json_object_add_string_copy (&node, "locator_set",
4335                                        mp->locator_set_name);
4336     }
4337
4338   vec_free (status);
4339
4340   vat_json_print (vam->ofp, &node);
4341   vat_json_free (&node);
4342
4343   vam->retval = ntohl (mp->retval);
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_show_one_map_register_ttl_reply_t_handler
4349   (vl_api_show_one_map_register_ttl_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   i32 retval = ntohl (mp->retval);
4353
4354   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "ttl: %u", mp->ttl);
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_show_one_map_register_ttl_reply_t_handler_json
4367   (vl_api_show_one_map_register_ttl_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371
4372   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4373   vat_json_init_object (&node);
4374   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   if (0 <= retval)
4390     {
4391       print (vam->ofp, "%-20s%-16s",
4392              mp->status ? "enabled" : "disabled",
4393              mp->status ? (char *) mp->locator_set_name : "");
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406
4407   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "status", status);
4412   if (mp->status)
4413     {
4414       vat_json_object_add_string_copy (&node, "locator_set",
4415                                        mp->locator_set_name);
4416     }
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static u8 *
4428 format_policer_type (u8 * s, va_list * va)
4429 {
4430   u32 i = va_arg (*va, u32);
4431
4432   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4433     s = format (s, "1r2c");
4434   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4435     s = format (s, "1r3c");
4436   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4437     s = format (s, "2r3c-2698");
4438   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4439     s = format (s, "2r3c-4115");
4440   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4441     s = format (s, "2r3c-mef5cf1");
4442   else
4443     s = format (s, "ILLEGAL");
4444   return s;
4445 }
4446
4447 static u8 *
4448 format_policer_rate_type (u8 * s, va_list * va)
4449 {
4450   u32 i = va_arg (*va, u32);
4451
4452   if (i == SSE2_QOS_RATE_KBPS)
4453     s = format (s, "kbps");
4454   else if (i == SSE2_QOS_RATE_PPS)
4455     s = format (s, "pps");
4456   else
4457     s = format (s, "ILLEGAL");
4458   return s;
4459 }
4460
4461 static u8 *
4462 format_policer_round_type (u8 * s, va_list * va)
4463 {
4464   u32 i = va_arg (*va, u32);
4465
4466   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4467     s = format (s, "closest");
4468   else if (i == SSE2_QOS_ROUND_TO_UP)
4469     s = format (s, "up");
4470   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4471     s = format (s, "down");
4472   else
4473     s = format (s, "ILLEGAL");
4474   return s;
4475 }
4476
4477 static u8 *
4478 format_policer_action_type (u8 * s, va_list * va)
4479 {
4480   u32 i = va_arg (*va, u32);
4481
4482   if (i == SSE2_QOS_ACTION_DROP)
4483     s = format (s, "drop");
4484   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4485     s = format (s, "transmit");
4486   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4487     s = format (s, "mark-and-transmit");
4488   else
4489     s = format (s, "ILLEGAL");
4490   return s;
4491 }
4492
4493 static u8 *
4494 format_dscp (u8 * s, va_list * va)
4495 {
4496   u32 i = va_arg (*va, u32);
4497   char *t = 0;
4498
4499   switch (i)
4500     {
4501 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4502       foreach_vnet_dscp
4503 #undef _
4504     default:
4505       return format (s, "ILLEGAL");
4506     }
4507   s = format (s, "%s", t);
4508   return s;
4509 }
4510
4511 static void
4512 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4516
4517   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4518     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4519   else
4520     conform_dscp_str = format (0, "");
4521
4522   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4523     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4524   else
4525     exceed_dscp_str = format (0, "");
4526
4527   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4528     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4529   else
4530     violate_dscp_str = format (0, "");
4531
4532   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4533          "rate type %U, round type %U, %s rate, %s color-aware, "
4534          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4535          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4536          "conform action %U%s, exceed action %U%s, violate action %U%s",
4537          mp->name,
4538          format_policer_type, mp->type,
4539          ntohl (mp->cir),
4540          ntohl (mp->eir),
4541          clib_net_to_host_u64 (mp->cb),
4542          clib_net_to_host_u64 (mp->eb),
4543          format_policer_rate_type, mp->rate_type,
4544          format_policer_round_type, mp->round_type,
4545          mp->single_rate ? "single" : "dual",
4546          mp->color_aware ? "is" : "not",
4547          ntohl (mp->cir_tokens_per_period),
4548          ntohl (mp->pir_tokens_per_period),
4549          ntohl (mp->scale),
4550          ntohl (mp->current_limit),
4551          ntohl (mp->current_bucket),
4552          ntohl (mp->extended_limit),
4553          ntohl (mp->extended_bucket),
4554          clib_net_to_host_u64 (mp->last_update_time),
4555          format_policer_action_type, mp->conform_action_type,
4556          conform_dscp_str,
4557          format_policer_action_type, mp->exceed_action_type,
4558          exceed_dscp_str,
4559          format_policer_action_type, mp->violate_action_type,
4560          violate_dscp_str);
4561
4562   vec_free (conform_dscp_str);
4563   vec_free (exceed_dscp_str);
4564   vec_free (violate_dscp_str);
4565 }
4566
4567 static void vl_api_policer_details_t_handler_json
4568   (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t *node;
4572   u8 *rate_type_str, *round_type_str, *type_str;
4573   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4574
4575   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4576   round_type_str =
4577     format (0, "%U", format_policer_round_type, mp->round_type);
4578   type_str = format (0, "%U", format_policer_type, mp->type);
4579   conform_action_str = format (0, "%U", format_policer_action_type,
4580                                mp->conform_action_type);
4581   exceed_action_str = format (0, "%U", format_policer_action_type,
4582                               mp->exceed_action_type);
4583   violate_action_str = format (0, "%U", format_policer_action_type,
4584                                mp->violate_action_type);
4585
4586   if (VAT_JSON_ARRAY != vam->json_tree.type)
4587     {
4588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4589       vat_json_init_array (&vam->json_tree);
4590     }
4591   node = vat_json_array_add (&vam->json_tree);
4592
4593   vat_json_init_object (node);
4594   vat_json_object_add_string_copy (node, "name", mp->name);
4595   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4596   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4597   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4598   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4599   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4600   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4601   vat_json_object_add_string_copy (node, "type", type_str);
4602   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4603   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4604   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4605   vat_json_object_add_uint (node, "cir_tokens_per_period",
4606                             ntohl (mp->cir_tokens_per_period));
4607   vat_json_object_add_uint (node, "eir_tokens_per_period",
4608                             ntohl (mp->pir_tokens_per_period));
4609   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4610   vat_json_object_add_uint (node, "current_bucket",
4611                             ntohl (mp->current_bucket));
4612   vat_json_object_add_uint (node, "extended_limit",
4613                             ntohl (mp->extended_limit));
4614   vat_json_object_add_uint (node, "extended_bucket",
4615                             ntohl (mp->extended_bucket));
4616   vat_json_object_add_uint (node, "last_update_time",
4617                             ntohl (mp->last_update_time));
4618   vat_json_object_add_string_copy (node, "conform_action",
4619                                    conform_action_str);
4620   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4621     {
4622       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4623       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4624       vec_free (dscp_str);
4625     }
4626   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4627   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4628     {
4629       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4630       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4631       vec_free (dscp_str);
4632     }
4633   vat_json_object_add_string_copy (node, "violate_action",
4634                                    violate_action_str);
4635   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4638       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641
4642   vec_free (rate_type_str);
4643   vec_free (round_type_str);
4644   vec_free (type_str);
4645   vec_free (conform_action_str);
4646   vec_free (exceed_action_str);
4647   vec_free (violate_action_str);
4648 }
4649
4650 static void
4651 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4652                                            mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   int i, count = ntohl (mp->count);
4656
4657   if (count > 0)
4658     print (vam->ofp, "classify table ids (%d) : ", count);
4659   for (i = 0; i < count; i++)
4660     {
4661       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4662       print (vam->ofp, (i < count - 1) ? "," : "");
4663     }
4664   vam->retval = ntohl (mp->retval);
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_classify_table_ids_reply_t_handler_json
4670   (vl_api_classify_table_ids_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   int i, count = ntohl (mp->count);
4674
4675   if (count > 0)
4676     {
4677       vat_json_node_t node;
4678
4679       vat_json_init_object (&node);
4680       for (i = 0; i < count; i++)
4681         {
4682           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4683         }
4684       vat_json_print (vam->ofp, &node);
4685       vat_json_free (&node);
4686     }
4687   vam->retval = ntohl (mp->retval);
4688   vam->result_ready = 1;
4689 }
4690
4691 static void
4692   vl_api_classify_table_by_interface_reply_t_handler
4693   (vl_api_classify_table_by_interface_reply_t * mp)
4694 {
4695   vat_main_t *vam = &vat_main;
4696   u32 table_id;
4697
4698   table_id = ntohl (mp->l2_table_id);
4699   if (table_id != ~0)
4700     print (vam->ofp, "l2 table id : %d", table_id);
4701   else
4702     print (vam->ofp, "l2 table id : No input ACL tables configured");
4703   table_id = ntohl (mp->ip4_table_id);
4704   if (table_id != ~0)
4705     print (vam->ofp, "ip4 table id : %d", table_id);
4706   else
4707     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4708   table_id = ntohl (mp->ip6_table_id);
4709   if (table_id != ~0)
4710     print (vam->ofp, "ip6 table id : %d", table_id);
4711   else
4712     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4713   vam->retval = ntohl (mp->retval);
4714   vam->result_ready = 1;
4715 }
4716
4717 static void
4718   vl_api_classify_table_by_interface_reply_t_handler_json
4719   (vl_api_classify_table_by_interface_reply_t * mp)
4720 {
4721   vat_main_t *vam = &vat_main;
4722   vat_json_node_t node;
4723
4724   vat_json_init_object (&node);
4725
4726   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4727   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4728   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4729
4730   vat_json_print (vam->ofp, &node);
4731   vat_json_free (&node);
4732
4733   vam->retval = ntohl (mp->retval);
4734   vam->result_ready = 1;
4735 }
4736
4737 static void vl_api_policer_add_del_reply_t_handler
4738   (vl_api_policer_add_del_reply_t * mp)
4739 {
4740   vat_main_t *vam = &vat_main;
4741   i32 retval = ntohl (mp->retval);
4742   if (vam->async_mode)
4743     {
4744       vam->async_errors += (retval < 0);
4745     }
4746   else
4747     {
4748       vam->retval = retval;
4749       vam->result_ready = 1;
4750       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4751         /*
4752          * Note: this is just barely thread-safe, depends on
4753          * the main thread spinning waiting for an answer...
4754          */
4755         errmsg ("policer index %d", ntohl (mp->policer_index));
4756     }
4757 }
4758
4759 static void vl_api_policer_add_del_reply_t_handler_json
4760   (vl_api_policer_add_del_reply_t * mp)
4761 {
4762   vat_main_t *vam = &vat_main;
4763   vat_json_node_t node;
4764
4765   vat_json_init_object (&node);
4766   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4767   vat_json_object_add_uint (&node, "policer_index",
4768                             ntohl (mp->policer_index));
4769
4770   vat_json_print (vam->ofp, &node);
4771   vat_json_free (&node);
4772
4773   vam->retval = ntohl (mp->retval);
4774   vam->result_ready = 1;
4775 }
4776
4777 /* Format hex dump. */
4778 u8 *
4779 format_hex_bytes (u8 * s, va_list * va)
4780 {
4781   u8 *bytes = va_arg (*va, u8 *);
4782   int n_bytes = va_arg (*va, int);
4783   uword i;
4784
4785   /* Print short or long form depending on byte count. */
4786   uword short_form = n_bytes <= 32;
4787   u32 indent = format_get_indent (s);
4788
4789   if (n_bytes == 0)
4790     return s;
4791
4792   for (i = 0; i < n_bytes; i++)
4793     {
4794       if (!short_form && (i % 32) == 0)
4795         s = format (s, "%08x: ", i);
4796       s = format (s, "%02x", bytes[i]);
4797       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4798         s = format (s, "\n%U", format_white_space, indent);
4799     }
4800
4801   return s;
4802 }
4803
4804 static void
4805 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4806                                             * mp)
4807 {
4808   vat_main_t *vam = &vat_main;
4809   i32 retval = ntohl (mp->retval);
4810   if (retval == 0)
4811     {
4812       print (vam->ofp, "classify table info :");
4813       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4814              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4815              ntohl (mp->miss_next_index));
4816       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4817              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4818              ntohl (mp->match_n_vectors));
4819       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4820              ntohl (mp->mask_length));
4821     }
4822   vam->retval = retval;
4823   vam->result_ready = 1;
4824 }
4825
4826 static void
4827   vl_api_classify_table_info_reply_t_handler_json
4828   (vl_api_classify_table_info_reply_t * mp)
4829 {
4830   vat_main_t *vam = &vat_main;
4831   vat_json_node_t node;
4832
4833   i32 retval = ntohl (mp->retval);
4834   if (retval == 0)
4835     {
4836       vat_json_init_object (&node);
4837
4838       vat_json_object_add_int (&node, "sessions",
4839                                ntohl (mp->active_sessions));
4840       vat_json_object_add_int (&node, "nexttbl",
4841                                ntohl (mp->next_table_index));
4842       vat_json_object_add_int (&node, "nextnode",
4843                                ntohl (mp->miss_next_index));
4844       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4845       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4846       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4847       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4848                       ntohl (mp->mask_length), 0);
4849       vat_json_object_add_string_copy (&node, "mask", s);
4850
4851       vat_json_print (vam->ofp, &node);
4852       vat_json_free (&node);
4853     }
4854   vam->retval = ntohl (mp->retval);
4855   vam->result_ready = 1;
4856 }
4857
4858 static void
4859 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4860                                            mp)
4861 {
4862   vat_main_t *vam = &vat_main;
4863
4864   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4865          ntohl (mp->hit_next_index), ntohl (mp->advance),
4866          ntohl (mp->opaque_index));
4867   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4868          ntohl (mp->match_length));
4869 }
4870
4871 static void
4872   vl_api_classify_session_details_t_handler_json
4873   (vl_api_classify_session_details_t * mp)
4874 {
4875   vat_main_t *vam = &vat_main;
4876   vat_json_node_t *node = NULL;
4877
4878   if (VAT_JSON_ARRAY != vam->json_tree.type)
4879     {
4880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4881       vat_json_init_array (&vam->json_tree);
4882     }
4883   node = vat_json_array_add (&vam->json_tree);
4884
4885   vat_json_init_object (node);
4886   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4887   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4888   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4889   u8 *s =
4890     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4891             0);
4892   vat_json_object_add_string_copy (node, "match", s);
4893 }
4894
4895 static void vl_api_pg_create_interface_reply_t_handler
4896   (vl_api_pg_create_interface_reply_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899
4900   vam->retval = ntohl (mp->retval);
4901   vam->result_ready = 1;
4902 }
4903
4904 static void vl_api_pg_create_interface_reply_t_handler_json
4905   (vl_api_pg_create_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   i32 retval = ntohl (mp->retval);
4911   if (retval == 0)
4912     {
4913       vat_json_init_object (&node);
4914
4915       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4916
4917       vat_json_print (vam->ofp, &node);
4918       vat_json_free (&node);
4919     }
4920   vam->retval = ntohl (mp->retval);
4921   vam->result_ready = 1;
4922 }
4923
4924 static void vl_api_policer_classify_details_t_handler
4925   (vl_api_policer_classify_details_t * mp)
4926 {
4927   vat_main_t *vam = &vat_main;
4928
4929   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4930          ntohl (mp->table_index));
4931 }
4932
4933 static void vl_api_policer_classify_details_t_handler_json
4934   (vl_api_policer_classify_details_t * mp)
4935 {
4936   vat_main_t *vam = &vat_main;
4937   vat_json_node_t *node;
4938
4939   if (VAT_JSON_ARRAY != vam->json_tree.type)
4940     {
4941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4942       vat_json_init_array (&vam->json_tree);
4943     }
4944   node = vat_json_array_add (&vam->json_tree);
4945
4946   vat_json_init_object (node);
4947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4948   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4949 }
4950
4951 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4952   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955   i32 retval = ntohl (mp->retval);
4956   if (vam->async_mode)
4957     {
4958       vam->async_errors += (retval < 0);
4959     }
4960   else
4961     {
4962       vam->retval = retval;
4963       vam->sw_if_index = ntohl (mp->sw_if_index);
4964       vam->result_ready = 1;
4965     }
4966 }
4967
4968 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4969   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t node;
4973
4974   vat_json_init_object (&node);
4975   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4976   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4977
4978   vat_json_print (vam->ofp, &node);
4979   vat_json_free (&node);
4980
4981   vam->retval = ntohl (mp->retval);
4982   vam->result_ready = 1;
4983 }
4984
4985 static void vl_api_flow_classify_details_t_handler
4986   (vl_api_flow_classify_details_t * mp)
4987 {
4988   vat_main_t *vam = &vat_main;
4989
4990   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4991          ntohl (mp->table_index));
4992 }
4993
4994 static void vl_api_flow_classify_details_t_handler_json
4995   (vl_api_flow_classify_details_t * mp)
4996 {
4997   vat_main_t *vam = &vat_main;
4998   vat_json_node_t *node;
4999
5000   if (VAT_JSON_ARRAY != vam->json_tree.type)
5001     {
5002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5003       vat_json_init_array (&vam->json_tree);
5004     }
5005   node = vat_json_array_add (&vam->json_tree);
5006
5007   vat_json_init_object (node);
5008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5009   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5010 }
5011
5012 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5013 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5014 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5015 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5016 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5017 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5018 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5019 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5020 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5021 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5022 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5023 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5024 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5025 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5026 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5031 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5032 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5033 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5034
5035 /*
5036  * Generate boilerplate reply handlers, which
5037  * dig the return value out of the xxx_reply_t API message,
5038  * stick it into vam->retval, and set vam->result_ready
5039  *
5040  * Could also do this by pointing N message decode slots at
5041  * a single function, but that could break in subtle ways.
5042  */
5043
5044 #define foreach_standard_reply_retval_handler           \
5045 _(sw_interface_set_flags_reply)                         \
5046 _(sw_interface_add_del_address_reply)                   \
5047 _(sw_interface_set_table_reply)                         \
5048 _(sw_interface_set_mpls_enable_reply)                   \
5049 _(sw_interface_set_vpath_reply)                         \
5050 _(sw_interface_set_vxlan_bypass_reply)                  \
5051 _(sw_interface_set_geneve_bypass_reply)                 \
5052 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5053 _(sw_interface_set_l2_bridge_reply)                     \
5054 _(bridge_domain_add_del_reply)                          \
5055 _(sw_interface_set_l2_xconnect_reply)                   \
5056 _(l2fib_add_del_reply)                                  \
5057 _(l2fib_flush_int_reply)                                \
5058 _(l2fib_flush_bd_reply)                                 \
5059 _(ip_add_del_route_reply)                               \
5060 _(ip_table_add_del_reply)                               \
5061 _(ip_mroute_add_del_reply)                              \
5062 _(mpls_route_add_del_reply)                             \
5063 _(mpls_table_add_del_reply)                             \
5064 _(mpls_ip_bind_unbind_reply)                            \
5065 _(proxy_arp_add_del_reply)                              \
5066 _(proxy_arp_intfc_enable_disable_reply)                 \
5067 _(sw_interface_set_unnumbered_reply)                    \
5068 _(ip_neighbor_add_del_reply)                            \
5069 _(reset_vrf_reply)                                      \
5070 _(oam_add_del_reply)                                    \
5071 _(reset_fib_reply)                                      \
5072 _(dhcp_proxy_config_reply)                              \
5073 _(dhcp_proxy_set_vss_reply)                             \
5074 _(dhcp_client_config_reply)                             \
5075 _(set_ip_flow_hash_reply)                               \
5076 _(sw_interface_ip6_enable_disable_reply)                \
5077 _(sw_interface_ip6_set_link_local_address_reply)        \
5078 _(ip6nd_proxy_add_del_reply)                            \
5079 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5080 _(sw_interface_ip6nd_ra_config_reply)                   \
5081 _(set_arp_neighbor_limit_reply)                         \
5082 _(l2_patch_add_del_reply)                               \
5083 _(sr_policy_add_reply)                                  \
5084 _(sr_policy_mod_reply)                                  \
5085 _(sr_policy_del_reply)                                  \
5086 _(sr_localsid_add_del_reply)                            \
5087 _(sr_steering_add_del_reply)                            \
5088 _(classify_add_del_session_reply)                       \
5089 _(classify_set_interface_ip_table_reply)                \
5090 _(classify_set_interface_l2_tables_reply)               \
5091 _(l2tpv3_set_tunnel_cookies_reply)                      \
5092 _(l2tpv3_interface_enable_disable_reply)                \
5093 _(l2tpv3_set_lookup_key_reply)                          \
5094 _(l2_fib_clear_table_reply)                             \
5095 _(l2_interface_efp_filter_reply)                        \
5096 _(l2_interface_vlan_tag_rewrite_reply)                  \
5097 _(modify_vhost_user_if_reply)                           \
5098 _(delete_vhost_user_if_reply)                           \
5099 _(want_ip4_arp_events_reply)                            \
5100 _(want_ip6_nd_events_reply)                             \
5101 _(want_l2_macs_events_reply)                            \
5102 _(input_acl_set_interface_reply)                        \
5103 _(ipsec_spd_add_del_reply)                              \
5104 _(ipsec_interface_add_del_spd_reply)                    \
5105 _(ipsec_spd_add_del_entry_reply)                        \
5106 _(ipsec_sad_add_del_entry_reply)                        \
5107 _(ipsec_sa_set_key_reply)                               \
5108 _(ipsec_tunnel_if_add_del_reply)                        \
5109 _(ipsec_tunnel_if_set_key_reply)                        \
5110 _(ipsec_tunnel_if_set_sa_reply)                         \
5111 _(ikev2_profile_add_del_reply)                          \
5112 _(ikev2_profile_set_auth_reply)                         \
5113 _(ikev2_profile_set_id_reply)                           \
5114 _(ikev2_profile_set_ts_reply)                           \
5115 _(ikev2_set_local_key_reply)                            \
5116 _(ikev2_set_responder_reply)                            \
5117 _(ikev2_set_ike_transforms_reply)                       \
5118 _(ikev2_set_esp_transforms_reply)                       \
5119 _(ikev2_set_sa_lifetime_reply)                          \
5120 _(ikev2_initiate_sa_init_reply)                         \
5121 _(ikev2_initiate_del_ike_sa_reply)                      \
5122 _(ikev2_initiate_del_child_sa_reply)                    \
5123 _(ikev2_initiate_rekey_child_sa_reply)                  \
5124 _(delete_loopback_reply)                                \
5125 _(bd_ip_mac_add_del_reply)                              \
5126 _(map_del_domain_reply)                                 \
5127 _(map_add_del_rule_reply)                               \
5128 _(want_interface_events_reply)                          \
5129 _(want_stats_reply)                                     \
5130 _(cop_interface_enable_disable_reply)                   \
5131 _(cop_whitelist_enable_disable_reply)                   \
5132 _(sw_interface_clear_stats_reply)                       \
5133 _(ioam_enable_reply)                                    \
5134 _(ioam_disable_reply)                                   \
5135 _(one_add_del_locator_reply)                            \
5136 _(one_add_del_local_eid_reply)                          \
5137 _(one_add_del_remote_mapping_reply)                     \
5138 _(one_add_del_adjacency_reply)                          \
5139 _(one_add_del_map_resolver_reply)                       \
5140 _(one_add_del_map_server_reply)                         \
5141 _(one_enable_disable_reply)                             \
5142 _(one_rloc_probe_enable_disable_reply)                  \
5143 _(one_map_register_enable_disable_reply)                \
5144 _(one_map_register_set_ttl_reply)                       \
5145 _(one_set_transport_protocol_reply)                     \
5146 _(one_map_register_fallback_threshold_reply)            \
5147 _(one_pitr_set_locator_set_reply)                       \
5148 _(one_map_request_mode_reply)                           \
5149 _(one_add_del_map_request_itr_rlocs_reply)              \
5150 _(one_eid_table_add_del_map_reply)                      \
5151 _(one_use_petr_reply)                                   \
5152 _(one_stats_enable_disable_reply)                       \
5153 _(one_add_del_l2_arp_entry_reply)                       \
5154 _(one_add_del_ndp_entry_reply)                          \
5155 _(one_stats_flush_reply)                                \
5156 _(gpe_enable_disable_reply)                             \
5157 _(gpe_set_encap_mode_reply)                             \
5158 _(gpe_add_del_iface_reply)                              \
5159 _(gpe_add_del_native_fwd_rpath_reply)                   \
5160 _(af_packet_delete_reply)                               \
5161 _(policer_classify_set_interface_reply)                 \
5162 _(netmap_create_reply)                                  \
5163 _(netmap_delete_reply)                                  \
5164 _(set_ipfix_exporter_reply)                             \
5165 _(set_ipfix_classify_stream_reply)                      \
5166 _(ipfix_classify_table_add_del_reply)                   \
5167 _(flow_classify_set_interface_reply)                    \
5168 _(sw_interface_span_enable_disable_reply)               \
5169 _(pg_capture_reply)                                     \
5170 _(pg_enable_disable_reply)                              \
5171 _(ip_source_and_port_range_check_add_del_reply)         \
5172 _(ip_source_and_port_range_check_interface_add_del_reply)\
5173 _(delete_subif_reply)                                   \
5174 _(l2_interface_pbb_tag_rewrite_reply)                   \
5175 _(punt_reply)                                           \
5176 _(feature_enable_disable_reply)                         \
5177 _(sw_interface_tag_add_del_reply)                       \
5178 _(sw_interface_set_mtu_reply)                           \
5179 _(p2p_ethernet_add_reply)                               \
5180 _(p2p_ethernet_del_reply)                               \
5181 _(lldp_config_reply)                                    \
5182 _(sw_interface_set_lldp_reply)                          \
5183 _(tcp_configure_src_addresses_reply)                    \
5184 _(app_namespace_add_del_reply)                          \
5185 _(dns_enable_disable_reply)                             \
5186 _(dns_name_server_add_del_reply)
5187
5188 #define _(n)                                    \
5189     static void vl_api_##n##_t_handler          \
5190     (vl_api_##n##_t * mp)                       \
5191     {                                           \
5192         vat_main_t * vam = &vat_main;           \
5193         i32 retval = ntohl(mp->retval);         \
5194         if (vam->async_mode) {                  \
5195             vam->async_errors += (retval < 0);  \
5196         } else {                                \
5197             vam->retval = retval;               \
5198             vam->result_ready = 1;              \
5199         }                                       \
5200     }
5201 foreach_standard_reply_retval_handler;
5202 #undef _
5203
5204 #define _(n)                                    \
5205     static void vl_api_##n##_t_handler_json     \
5206     (vl_api_##n##_t * mp)                       \
5207     {                                           \
5208         vat_main_t * vam = &vat_main;           \
5209         vat_json_node_t node;                   \
5210         vat_json_init_object(&node);            \
5211         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5212         vat_json_print(vam->ofp, &node);        \
5213         vam->retval = ntohl(mp->retval);        \
5214         vam->result_ready = 1;                  \
5215     }
5216 foreach_standard_reply_retval_handler;
5217 #undef _
5218
5219 /*
5220  * Table of message reply handlers, must include boilerplate handlers
5221  * we just generated
5222  */
5223
5224 #define foreach_vpe_api_reply_msg                                       \
5225 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5226 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5227 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5228 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5229 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5230 _(CLI_REPLY, cli_reply)                                                 \
5231 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5232 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5233   sw_interface_add_del_address_reply)                                   \
5234 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5235 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5236 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5237 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5238 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5239 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5240 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5241   sw_interface_set_l2_xconnect_reply)                                   \
5242 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5243   sw_interface_set_l2_bridge_reply)                                     \
5244 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5245 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5246 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5247 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5248 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5249 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5250 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5251 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5252 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5253 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5254 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5255 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5256 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5257 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5258 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5259 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5260 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5261 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5262 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5263 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5264   proxy_arp_intfc_enable_disable_reply)                                 \
5265 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5266 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5267   sw_interface_set_unnumbered_reply)                                    \
5268 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5269 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5270 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5271 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5272 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5273 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5274 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5275 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5276 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5277 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5278 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5279 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5280   sw_interface_ip6_enable_disable_reply)                                \
5281 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5282   sw_interface_ip6_set_link_local_address_reply)                        \
5283 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5284 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5285 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5286   sw_interface_ip6nd_ra_prefix_reply)                                   \
5287 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5288   sw_interface_ip6nd_ra_config_reply)                                   \
5289 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5290 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5291 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5292 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5293 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5294 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5295 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5296 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5297 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5298 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5299 classify_set_interface_ip_table_reply)                                  \
5300 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5301   classify_set_interface_l2_tables_reply)                               \
5302 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5303 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5304 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5305 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5306 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5307   l2tpv3_interface_enable_disable_reply)                                \
5308 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5309 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5310 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5311 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5312 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5313 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5314 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5315 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5316 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5317 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5318 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5319 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5320 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5321 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5322 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5323 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5324 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5325 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5326 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5327 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5328 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5329 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5330 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5331 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5332 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5333 _(L2_MACS_EVENT, l2_macs_event)                                         \
5334 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5335 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5336 _(IP_DETAILS, ip_details)                                               \
5337 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5338 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5339 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5340 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5341 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5342 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5343 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5344 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5345 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5346 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5347 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5348 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5349 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5350 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5351 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5352 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5353 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5354 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5355 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5356 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5357 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5358 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5359 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5360 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5361 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5362 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5363 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5364 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5365 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5366 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5367 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5368 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5369 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5370 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5371 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5372 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5373 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5374 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5375 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5376 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5377 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5378 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5379 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5380 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5381 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5382 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5383 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5384 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5385   one_map_register_enable_disable_reply)                                \
5386 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5387 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5388 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5389 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5390   one_map_register_fallback_threshold_reply)                            \
5391 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5392   one_rloc_probe_enable_disable_reply)                                  \
5393 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5394 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5395 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5396 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5397 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5398 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5399 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5400 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5401 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5402 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5403 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5404 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5405 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5406 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5407 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5408 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5409   show_one_stats_enable_disable_reply)                                  \
5410 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5411 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5412 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5413 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5414 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5415 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5416 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5417 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5418 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5419 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5420 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5421 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5422 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5423 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5424 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5425   gpe_add_del_native_fwd_rpath_reply)                                   \
5426 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5427   gpe_fwd_entry_path_details)                                           \
5428 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5429 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5430   one_add_del_map_request_itr_rlocs_reply)                              \
5431 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5432   one_get_map_request_itr_rlocs_reply)                                  \
5433 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5434 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5435 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5436 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5437 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5438 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5439   show_one_map_register_state_reply)                                    \
5440 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5442   show_one_map_register_fallback_threshold_reply)                       \
5443 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5444 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5445 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5446 _(POLICER_DETAILS, policer_details)                                     \
5447 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5448 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5449 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5450 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5451 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5452 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5453 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5454 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5455 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5456 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5457 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5458 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5459 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5460 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5461 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5462 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5463 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5464 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5465 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5466 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5467 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5468 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5469 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5470 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5471 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5472  ip_source_and_port_range_check_add_del_reply)                          \
5473 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5474  ip_source_and_port_range_check_interface_add_del_reply)                \
5475 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5476 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5477 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5478 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5479 _(PUNT_REPLY, punt_reply)                                               \
5480 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5481 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5482 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5483 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5484 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5485 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5486 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5487 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5488 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5489 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5490 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5491 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5492 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5493 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5494 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5495 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5496 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5497 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)
5498
5499 #define foreach_standalone_reply_msg                                    \
5500 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5501 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5502 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5503 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5504 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5505 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5506 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5507 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5508
5509 typedef struct
5510 {
5511   u8 *name;
5512   u32 value;
5513 } name_sort_t;
5514
5515
5516 #define STR_VTR_OP_CASE(op)     \
5517     case L2_VTR_ ## op:         \
5518         return "" # op;
5519
5520 static const char *
5521 str_vtr_op (u32 vtr_op)
5522 {
5523   switch (vtr_op)
5524     {
5525       STR_VTR_OP_CASE (DISABLED);
5526       STR_VTR_OP_CASE (PUSH_1);
5527       STR_VTR_OP_CASE (PUSH_2);
5528       STR_VTR_OP_CASE (POP_1);
5529       STR_VTR_OP_CASE (POP_2);
5530       STR_VTR_OP_CASE (TRANSLATE_1_1);
5531       STR_VTR_OP_CASE (TRANSLATE_1_2);
5532       STR_VTR_OP_CASE (TRANSLATE_2_1);
5533       STR_VTR_OP_CASE (TRANSLATE_2_2);
5534     }
5535
5536   return "UNKNOWN";
5537 }
5538
5539 static int
5540 dump_sub_interface_table (vat_main_t * vam)
5541 {
5542   const sw_interface_subif_t *sub = NULL;
5543
5544   if (vam->json_output)
5545     {
5546       clib_warning
5547         ("JSON output supported only for VPE API calls and dump_stats_table");
5548       return -99;
5549     }
5550
5551   print (vam->ofp,
5552          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5553          "Interface", "sw_if_index",
5554          "sub id", "dot1ad", "tags", "outer id",
5555          "inner id", "exact", "default", "outer any", "inner any");
5556
5557   vec_foreach (sub, vam->sw_if_subif_table)
5558   {
5559     print (vam->ofp,
5560            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5561            sub->interface_name,
5562            sub->sw_if_index,
5563            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5564            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5565            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5566            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5567     if (sub->vtr_op != L2_VTR_DISABLED)
5568       {
5569         print (vam->ofp,
5570                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5571                "tag1: %d tag2: %d ]",
5572                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5573                sub->vtr_tag1, sub->vtr_tag2);
5574       }
5575   }
5576
5577   return 0;
5578 }
5579
5580 static int
5581 name_sort_cmp (void *a1, void *a2)
5582 {
5583   name_sort_t *n1 = a1;
5584   name_sort_t *n2 = a2;
5585
5586   return strcmp ((char *) n1->name, (char *) n2->name);
5587 }
5588
5589 static int
5590 dump_interface_table (vat_main_t * vam)
5591 {
5592   hash_pair_t *p;
5593   name_sort_t *nses = 0, *ns;
5594
5595   if (vam->json_output)
5596     {
5597       clib_warning
5598         ("JSON output supported only for VPE API calls and dump_stats_table");
5599       return -99;
5600     }
5601
5602   /* *INDENT-OFF* */
5603   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5604   ({
5605     vec_add2 (nses, ns, 1);
5606     ns->name = (u8 *)(p->key);
5607     ns->value = (u32) p->value[0];
5608   }));
5609   /* *INDENT-ON* */
5610
5611   vec_sort_with_function (nses, name_sort_cmp);
5612
5613   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5614   vec_foreach (ns, nses)
5615   {
5616     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5617   }
5618   vec_free (nses);
5619   return 0;
5620 }
5621
5622 static int
5623 dump_ip_table (vat_main_t * vam, int is_ipv6)
5624 {
5625   const ip_details_t *det = NULL;
5626   const ip_address_details_t *address = NULL;
5627   u32 i = ~0;
5628
5629   print (vam->ofp, "%-12s", "sw_if_index");
5630
5631   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5632   {
5633     i++;
5634     if (!det->present)
5635       {
5636         continue;
5637       }
5638     print (vam->ofp, "%-12d", i);
5639     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5640     if (!det->addr)
5641       {
5642         continue;
5643       }
5644     vec_foreach (address, det->addr)
5645     {
5646       print (vam->ofp,
5647              "            %-30U%-13d",
5648              is_ipv6 ? format_ip6_address : format_ip4_address,
5649              address->ip, address->prefix_length);
5650     }
5651   }
5652
5653   return 0;
5654 }
5655
5656 static int
5657 dump_ipv4_table (vat_main_t * vam)
5658 {
5659   if (vam->json_output)
5660     {
5661       clib_warning
5662         ("JSON output supported only for VPE API calls and dump_stats_table");
5663       return -99;
5664     }
5665
5666   return dump_ip_table (vam, 0);
5667 }
5668
5669 static int
5670 dump_ipv6_table (vat_main_t * vam)
5671 {
5672   if (vam->json_output)
5673     {
5674       clib_warning
5675         ("JSON output supported only for VPE API calls and dump_stats_table");
5676       return -99;
5677     }
5678
5679   return dump_ip_table (vam, 1);
5680 }
5681
5682 static char *
5683 counter_type_to_str (u8 counter_type, u8 is_combined)
5684 {
5685   if (!is_combined)
5686     {
5687       switch (counter_type)
5688         {
5689         case VNET_INTERFACE_COUNTER_DROP:
5690           return "drop";
5691         case VNET_INTERFACE_COUNTER_PUNT:
5692           return "punt";
5693         case VNET_INTERFACE_COUNTER_IP4:
5694           return "ip4";
5695         case VNET_INTERFACE_COUNTER_IP6:
5696           return "ip6";
5697         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5698           return "rx-no-buf";
5699         case VNET_INTERFACE_COUNTER_RX_MISS:
5700           return "rx-miss";
5701         case VNET_INTERFACE_COUNTER_RX_ERROR:
5702           return "rx-error";
5703         case VNET_INTERFACE_COUNTER_TX_ERROR:
5704           return "tx-error";
5705         default:
5706           return "INVALID-COUNTER-TYPE";
5707         }
5708     }
5709   else
5710     {
5711       switch (counter_type)
5712         {
5713         case VNET_INTERFACE_COUNTER_RX:
5714           return "rx";
5715         case VNET_INTERFACE_COUNTER_TX:
5716           return "tx";
5717         default:
5718           return "INVALID-COUNTER-TYPE";
5719         }
5720     }
5721 }
5722
5723 static int
5724 dump_stats_table (vat_main_t * vam)
5725 {
5726   vat_json_node_t node;
5727   vat_json_node_t *msg_array;
5728   vat_json_node_t *msg;
5729   vat_json_node_t *counter_array;
5730   vat_json_node_t *counter;
5731   interface_counter_t c;
5732   u64 packets;
5733   ip4_fib_counter_t *c4;
5734   ip6_fib_counter_t *c6;
5735   ip4_nbr_counter_t *n4;
5736   ip6_nbr_counter_t *n6;
5737   int i, j;
5738
5739   if (!vam->json_output)
5740     {
5741       clib_warning ("dump_stats_table supported only in JSON format");
5742       return -99;
5743     }
5744
5745   vat_json_init_object (&node);
5746
5747   /* interface counters */
5748   msg_array = vat_json_object_add (&node, "interface_counters");
5749   vat_json_init_array (msg_array);
5750   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5751     {
5752       msg = vat_json_array_add (msg_array);
5753       vat_json_init_object (msg);
5754       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5755                                        (u8 *) counter_type_to_str (i, 0));
5756       vat_json_object_add_int (msg, "is_combined", 0);
5757       counter_array = vat_json_object_add (msg, "data");
5758       vat_json_init_array (counter_array);
5759       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5760         {
5761           packets = vam->simple_interface_counters[i][j];
5762           vat_json_array_add_uint (counter_array, packets);
5763         }
5764     }
5765   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5766     {
5767       msg = vat_json_array_add (msg_array);
5768       vat_json_init_object (msg);
5769       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5770                                        (u8 *) counter_type_to_str (i, 1));
5771       vat_json_object_add_int (msg, "is_combined", 1);
5772       counter_array = vat_json_object_add (msg, "data");
5773       vat_json_init_array (counter_array);
5774       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5775         {
5776           c = vam->combined_interface_counters[i][j];
5777           counter = vat_json_array_add (counter_array);
5778           vat_json_init_object (counter);
5779           vat_json_object_add_uint (counter, "packets", c.packets);
5780           vat_json_object_add_uint (counter, "bytes", c.bytes);
5781         }
5782     }
5783
5784   /* ip4 fib counters */
5785   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5786   vat_json_init_array (msg_array);
5787   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5788     {
5789       msg = vat_json_array_add (msg_array);
5790       vat_json_init_object (msg);
5791       vat_json_object_add_uint (msg, "vrf_id",
5792                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5793       counter_array = vat_json_object_add (msg, "c");
5794       vat_json_init_array (counter_array);
5795       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5796         {
5797           counter = vat_json_array_add (counter_array);
5798           vat_json_init_object (counter);
5799           c4 = &vam->ip4_fib_counters[i][j];
5800           vat_json_object_add_ip4 (counter, "address", c4->address);
5801           vat_json_object_add_uint (counter, "address_length",
5802                                     c4->address_length);
5803           vat_json_object_add_uint (counter, "packets", c4->packets);
5804           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5805         }
5806     }
5807
5808   /* ip6 fib counters */
5809   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5810   vat_json_init_array (msg_array);
5811   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5812     {
5813       msg = vat_json_array_add (msg_array);
5814       vat_json_init_object (msg);
5815       vat_json_object_add_uint (msg, "vrf_id",
5816                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5817       counter_array = vat_json_object_add (msg, "c");
5818       vat_json_init_array (counter_array);
5819       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5820         {
5821           counter = vat_json_array_add (counter_array);
5822           vat_json_init_object (counter);
5823           c6 = &vam->ip6_fib_counters[i][j];
5824           vat_json_object_add_ip6 (counter, "address", c6->address);
5825           vat_json_object_add_uint (counter, "address_length",
5826                                     c6->address_length);
5827           vat_json_object_add_uint (counter, "packets", c6->packets);
5828           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5829         }
5830     }
5831
5832   /* ip4 nbr counters */
5833   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5834   vat_json_init_array (msg_array);
5835   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5836     {
5837       msg = vat_json_array_add (msg_array);
5838       vat_json_init_object (msg);
5839       vat_json_object_add_uint (msg, "sw_if_index", i);
5840       counter_array = vat_json_object_add (msg, "c");
5841       vat_json_init_array (counter_array);
5842       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5843         {
5844           counter = vat_json_array_add (counter_array);
5845           vat_json_init_object (counter);
5846           n4 = &vam->ip4_nbr_counters[i][j];
5847           vat_json_object_add_ip4 (counter, "address", n4->address);
5848           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5849           vat_json_object_add_uint (counter, "packets", n4->packets);
5850           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5851         }
5852     }
5853
5854   /* ip6 nbr counters */
5855   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5856   vat_json_init_array (msg_array);
5857   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5858     {
5859       msg = vat_json_array_add (msg_array);
5860       vat_json_init_object (msg);
5861       vat_json_object_add_uint (msg, "sw_if_index", i);
5862       counter_array = vat_json_object_add (msg, "c");
5863       vat_json_init_array (counter_array);
5864       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5865         {
5866           counter = vat_json_array_add (counter_array);
5867           vat_json_init_object (counter);
5868           n6 = &vam->ip6_nbr_counters[i][j];
5869           vat_json_object_add_ip6 (counter, "address", n6->address);
5870           vat_json_object_add_uint (counter, "packets", n6->packets);
5871           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5872         }
5873     }
5874
5875   vat_json_print (vam->ofp, &node);
5876   vat_json_free (&node);
5877
5878   return 0;
5879 }
5880
5881 /*
5882  * Pass CLI buffers directly in the CLI_INBAND API message,
5883  * instead of an additional shared memory area.
5884  */
5885 static int
5886 exec_inband (vat_main_t * vam)
5887 {
5888   vl_api_cli_inband_t *mp;
5889   unformat_input_t *i = vam->input;
5890   int ret;
5891
5892   if (vec_len (i->buffer) == 0)
5893     return -1;
5894
5895   if (vam->exec_mode == 0 && unformat (i, "mode"))
5896     {
5897       vam->exec_mode = 1;
5898       return 0;
5899     }
5900   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5901     {
5902       vam->exec_mode = 0;
5903       return 0;
5904     }
5905
5906   /*
5907    * In order for the CLI command to work, it
5908    * must be a vector ending in \n, not a C-string ending
5909    * in \n\0.
5910    */
5911   u32 len = vec_len (vam->input->buffer);
5912   M2 (CLI_INBAND, mp, len);
5913   clib_memcpy (mp->cmd, vam->input->buffer, len);
5914   mp->length = htonl (len);
5915
5916   S (mp);
5917   W (ret);
5918   /* json responses may or may not include a useful reply... */
5919   if (vec_len (vam->cmd_reply))
5920     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5921   return ret;
5922 }
5923
5924 int
5925 exec (vat_main_t * vam)
5926 {
5927   return exec_inband (vam);
5928 }
5929
5930 static int
5931 api_create_loopback (vat_main_t * vam)
5932 {
5933   unformat_input_t *i = vam->input;
5934   vl_api_create_loopback_t *mp;
5935   vl_api_create_loopback_instance_t *mp_lbi;
5936   u8 mac_address[6];
5937   u8 mac_set = 0;
5938   u8 is_specified = 0;
5939   u32 user_instance = 0;
5940   int ret;
5941
5942   memset (mac_address, 0, sizeof (mac_address));
5943
5944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5945     {
5946       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5947         mac_set = 1;
5948       if (unformat (i, "instance %d", &user_instance))
5949         is_specified = 1;
5950       else
5951         break;
5952     }
5953
5954   if (is_specified)
5955     {
5956       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5957       mp_lbi->is_specified = is_specified;
5958       if (is_specified)
5959         mp_lbi->user_instance = htonl (user_instance);
5960       if (mac_set)
5961         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5962       S (mp_lbi);
5963     }
5964   else
5965     {
5966       /* Construct the API message */
5967       M (CREATE_LOOPBACK, mp);
5968       if (mac_set)
5969         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5970       S (mp);
5971     }
5972
5973   W (ret);
5974   return ret;
5975 }
5976
5977 static int
5978 api_delete_loopback (vat_main_t * vam)
5979 {
5980   unformat_input_t *i = vam->input;
5981   vl_api_delete_loopback_t *mp;
5982   u32 sw_if_index = ~0;
5983   int ret;
5984
5985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5986     {
5987       if (unformat (i, "sw_if_index %d", &sw_if_index))
5988         ;
5989       else
5990         break;
5991     }
5992
5993   if (sw_if_index == ~0)
5994     {
5995       errmsg ("missing sw_if_index");
5996       return -99;
5997     }
5998
5999   /* Construct the API message */
6000   M (DELETE_LOOPBACK, mp);
6001   mp->sw_if_index = ntohl (sw_if_index);
6002
6003   S (mp);
6004   W (ret);
6005   return ret;
6006 }
6007
6008 static int
6009 api_want_stats (vat_main_t * vam)
6010 {
6011   unformat_input_t *i = vam->input;
6012   vl_api_want_stats_t *mp;
6013   int enable = -1;
6014   int ret;
6015
6016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6017     {
6018       if (unformat (i, "enable"))
6019         enable = 1;
6020       else if (unformat (i, "disable"))
6021         enable = 0;
6022       else
6023         break;
6024     }
6025
6026   if (enable == -1)
6027     {
6028       errmsg ("missing enable|disable");
6029       return -99;
6030     }
6031
6032   M (WANT_STATS, mp);
6033   mp->enable_disable = enable;
6034
6035   S (mp);
6036   W (ret);
6037   return ret;
6038 }
6039
6040 static int
6041 api_want_interface_events (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_want_interface_events_t *mp;
6045   int enable = -1;
6046   int ret;
6047
6048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6049     {
6050       if (unformat (i, "enable"))
6051         enable = 1;
6052       else if (unformat (i, "disable"))
6053         enable = 0;
6054       else
6055         break;
6056     }
6057
6058   if (enable == -1)
6059     {
6060       errmsg ("missing enable|disable");
6061       return -99;
6062     }
6063
6064   M (WANT_INTERFACE_EVENTS, mp);
6065   mp->enable_disable = enable;
6066
6067   vam->interface_event_display = enable;
6068
6069   S (mp);
6070   W (ret);
6071   return ret;
6072 }
6073
6074
6075 /* Note: non-static, called once to set up the initial intfc table */
6076 int
6077 api_sw_interface_dump (vat_main_t * vam)
6078 {
6079   vl_api_sw_interface_dump_t *mp;
6080   vl_api_control_ping_t *mp_ping;
6081   hash_pair_t *p;
6082   name_sort_t *nses = 0, *ns;
6083   sw_interface_subif_t *sub = NULL;
6084   int ret;
6085
6086   /* Toss the old name table */
6087   /* *INDENT-OFF* */
6088   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6089   ({
6090     vec_add2 (nses, ns, 1);
6091     ns->name = (u8 *)(p->key);
6092     ns->value = (u32) p->value[0];
6093   }));
6094   /* *INDENT-ON* */
6095
6096   hash_free (vam->sw_if_index_by_interface_name);
6097
6098   vec_foreach (ns, nses) vec_free (ns->name);
6099
6100   vec_free (nses);
6101
6102   vec_foreach (sub, vam->sw_if_subif_table)
6103   {
6104     vec_free (sub->interface_name);
6105   }
6106   vec_free (vam->sw_if_subif_table);
6107
6108   /* recreate the interface name hash table */
6109   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6110
6111   /* Get list of ethernets */
6112   M (SW_INTERFACE_DUMP, mp);
6113   mp->name_filter_valid = 1;
6114   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6115   S (mp);
6116
6117   /* and local / loopback interfaces */
6118   M (SW_INTERFACE_DUMP, mp);
6119   mp->name_filter_valid = 1;
6120   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6121   S (mp);
6122
6123   /* and packet-generator interfaces */
6124   M (SW_INTERFACE_DUMP, mp);
6125   mp->name_filter_valid = 1;
6126   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6127   S (mp);
6128
6129   /* and vxlan-gpe tunnel interfaces */
6130   M (SW_INTERFACE_DUMP, mp);
6131   mp->name_filter_valid = 1;
6132   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6133            sizeof (mp->name_filter) - 1);
6134   S (mp);
6135
6136   /* and vxlan tunnel interfaces */
6137   M (SW_INTERFACE_DUMP, mp);
6138   mp->name_filter_valid = 1;
6139   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6140   S (mp);
6141
6142   /* and geneve tunnel interfaces */
6143   M (SW_INTERFACE_DUMP, mp);
6144   mp->name_filter_valid = 1;
6145   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6146   S (mp);
6147
6148   /* and host (af_packet) interfaces */
6149   M (SW_INTERFACE_DUMP, mp);
6150   mp->name_filter_valid = 1;
6151   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6152   S (mp);
6153
6154   /* and l2tpv3 tunnel interfaces */
6155   M (SW_INTERFACE_DUMP, mp);
6156   mp->name_filter_valid = 1;
6157   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6158            sizeof (mp->name_filter) - 1);
6159   S (mp);
6160
6161   /* and GRE tunnel interfaces */
6162   M (SW_INTERFACE_DUMP, mp);
6163   mp->name_filter_valid = 1;
6164   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6165   S (mp);
6166
6167   /* and LISP-GPE interfaces */
6168   M (SW_INTERFACE_DUMP, mp);
6169   mp->name_filter_valid = 1;
6170   strncpy ((char *) mp->name_filter, "lisp_gpe",
6171            sizeof (mp->name_filter) - 1);
6172   S (mp);
6173
6174   /* and IPSEC tunnel interfaces */
6175   M (SW_INTERFACE_DUMP, mp);
6176   mp->name_filter_valid = 1;
6177   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6178   S (mp);
6179
6180   /* Use a control ping for synchronization */
6181   MPING (CONTROL_PING, mp_ping);
6182   S (mp_ping);
6183
6184   W (ret);
6185   return ret;
6186 }
6187
6188 static int
6189 api_sw_interface_set_flags (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_set_flags_t *mp;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195   u8 admin_up = 0;
6196   int ret;
6197
6198   /* Parse args required to build the message */
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "admin-up"))
6202         admin_up = 1;
6203       else if (unformat (i, "admin-down"))
6204         admin_up = 0;
6205       else
6206         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6207         sw_if_index_set = 1;
6208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6209         sw_if_index_set = 1;
6210       else
6211         break;
6212     }
6213
6214   if (sw_if_index_set == 0)
6215     {
6216       errmsg ("missing interface name or sw_if_index");
6217       return -99;
6218     }
6219
6220   /* Construct the API message */
6221   M (SW_INTERFACE_SET_FLAGS, mp);
6222   mp->sw_if_index = ntohl (sw_if_index);
6223   mp->admin_up_down = admin_up;
6224
6225   /* send it... */
6226   S (mp);
6227
6228   /* Wait for a reply, return the good/bad news... */
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_sw_interface_clear_stats (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_sw_interface_clear_stats_t *mp;
6238   u32 sw_if_index;
6239   u8 sw_if_index_set = 0;
6240   int ret;
6241
6242   /* Parse args required to build the message */
6243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6244     {
6245       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6246         sw_if_index_set = 1;
6247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6248         sw_if_index_set = 1;
6249       else
6250         break;
6251     }
6252
6253   /* Construct the API message */
6254   M (SW_INTERFACE_CLEAR_STATS, mp);
6255
6256   if (sw_if_index_set == 1)
6257     mp->sw_if_index = ntohl (sw_if_index);
6258   else
6259     mp->sw_if_index = ~0;
6260
6261   /* send it... */
6262   S (mp);
6263
6264   /* Wait for a reply, return the good/bad news... */
6265   W (ret);
6266   return ret;
6267 }
6268
6269 static int
6270 api_sw_interface_add_del_address (vat_main_t * vam)
6271 {
6272   unformat_input_t *i = vam->input;
6273   vl_api_sw_interface_add_del_address_t *mp;
6274   u32 sw_if_index;
6275   u8 sw_if_index_set = 0;
6276   u8 is_add = 1, del_all = 0;
6277   u32 address_length = 0;
6278   u8 v4_address_set = 0;
6279   u8 v6_address_set = 0;
6280   ip4_address_t v4address;
6281   ip6_address_t v6address;
6282   int ret;
6283
6284   /* Parse args required to build the message */
6285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6286     {
6287       if (unformat (i, "del-all"))
6288         del_all = 1;
6289       else if (unformat (i, "del"))
6290         is_add = 0;
6291       else
6292         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6293         sw_if_index_set = 1;
6294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6295         sw_if_index_set = 1;
6296       else if (unformat (i, "%U/%d",
6297                          unformat_ip4_address, &v4address, &address_length))
6298         v4_address_set = 1;
6299       else if (unformat (i, "%U/%d",
6300                          unformat_ip6_address, &v6address, &address_length))
6301         v6_address_set = 1;
6302       else
6303         break;
6304     }
6305
6306   if (sw_if_index_set == 0)
6307     {
6308       errmsg ("missing interface name or sw_if_index");
6309       return -99;
6310     }
6311   if (v4_address_set && v6_address_set)
6312     {
6313       errmsg ("both v4 and v6 addresses set");
6314       return -99;
6315     }
6316   if (!v4_address_set && !v6_address_set && !del_all)
6317     {
6318       errmsg ("no addresses set");
6319       return -99;
6320     }
6321
6322   /* Construct the API message */
6323   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6324
6325   mp->sw_if_index = ntohl (sw_if_index);
6326   mp->is_add = is_add;
6327   mp->del_all = del_all;
6328   if (v6_address_set)
6329     {
6330       mp->is_ipv6 = 1;
6331       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6332     }
6333   else
6334     {
6335       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6336     }
6337   mp->address_length = address_length;
6338
6339   /* send it... */
6340   S (mp);
6341
6342   /* Wait for a reply, return good/bad news  */
6343   W (ret);
6344   return ret;
6345 }
6346
6347 static int
6348 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6349 {
6350   unformat_input_t *i = vam->input;
6351   vl_api_sw_interface_set_mpls_enable_t *mp;
6352   u32 sw_if_index;
6353   u8 sw_if_index_set = 0;
6354   u8 enable = 1;
6355   int ret;
6356
6357   /* Parse args required to build the message */
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "disable"))
6365         enable = 0;
6366       else if (unformat (i, "dis"))
6367         enable = 0;
6368       else
6369         break;
6370     }
6371
6372   if (sw_if_index_set == 0)
6373     {
6374       errmsg ("missing interface name or sw_if_index");
6375       return -99;
6376     }
6377
6378   /* Construct the API message */
6379   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6380
6381   mp->sw_if_index = ntohl (sw_if_index);
6382   mp->enable = enable;
6383
6384   /* send it... */
6385   S (mp);
6386
6387   /* Wait for a reply... */
6388   W (ret);
6389   return ret;
6390 }
6391
6392 static int
6393 api_sw_interface_set_table (vat_main_t * vam)
6394 {
6395   unformat_input_t *i = vam->input;
6396   vl_api_sw_interface_set_table_t *mp;
6397   u32 sw_if_index, vrf_id = 0;
6398   u8 sw_if_index_set = 0;
6399   u8 is_ipv6 = 0;
6400   int ret;
6401
6402   /* Parse args required to build the message */
6403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6404     {
6405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "vrf %d", &vrf_id))
6410         ;
6411       else if (unformat (i, "ipv6"))
6412         is_ipv6 = 1;
6413       else
6414         break;
6415     }
6416
6417   if (sw_if_index_set == 0)
6418     {
6419       errmsg ("missing interface name or sw_if_index");
6420       return -99;
6421     }
6422
6423   /* Construct the API message */
6424   M (SW_INTERFACE_SET_TABLE, mp);
6425
6426   mp->sw_if_index = ntohl (sw_if_index);
6427   mp->is_ipv6 = is_ipv6;
6428   mp->vrf_id = ntohl (vrf_id);
6429
6430   /* send it... */
6431   S (mp);
6432
6433   /* Wait for a reply... */
6434   W (ret);
6435   return ret;
6436 }
6437
6438 static void vl_api_sw_interface_get_table_reply_t_handler
6439   (vl_api_sw_interface_get_table_reply_t * mp)
6440 {
6441   vat_main_t *vam = &vat_main;
6442
6443   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6444
6445   vam->retval = ntohl (mp->retval);
6446   vam->result_ready = 1;
6447
6448 }
6449
6450 static void vl_api_sw_interface_get_table_reply_t_handler_json
6451   (vl_api_sw_interface_get_table_reply_t * mp)
6452 {
6453   vat_main_t *vam = &vat_main;
6454   vat_json_node_t node;
6455
6456   vat_json_init_object (&node);
6457   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6458   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6459
6460   vat_json_print (vam->ofp, &node);
6461   vat_json_free (&node);
6462
6463   vam->retval = ntohl (mp->retval);
6464   vam->result_ready = 1;
6465 }
6466
6467 static int
6468 api_sw_interface_get_table (vat_main_t * vam)
6469 {
6470   unformat_input_t *i = vam->input;
6471   vl_api_sw_interface_get_table_t *mp;
6472   u32 sw_if_index;
6473   u8 sw_if_index_set = 0;
6474   u8 is_ipv6 = 0;
6475   int ret;
6476
6477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6478     {
6479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6480         sw_if_index_set = 1;
6481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6482         sw_if_index_set = 1;
6483       else if (unformat (i, "ipv6"))
6484         is_ipv6 = 1;
6485       else
6486         break;
6487     }
6488
6489   if (sw_if_index_set == 0)
6490     {
6491       errmsg ("missing interface name or sw_if_index");
6492       return -99;
6493     }
6494
6495   M (SW_INTERFACE_GET_TABLE, mp);
6496   mp->sw_if_index = htonl (sw_if_index);
6497   mp->is_ipv6 = is_ipv6;
6498
6499   S (mp);
6500   W (ret);
6501   return ret;
6502 }
6503
6504 static int
6505 api_sw_interface_set_vpath (vat_main_t * vam)
6506 {
6507   unformat_input_t *i = vam->input;
6508   vl_api_sw_interface_set_vpath_t *mp;
6509   u32 sw_if_index = 0;
6510   u8 sw_if_index_set = 0;
6511   u8 is_enable = 0;
6512   int ret;
6513
6514   /* Parse args required to build the message */
6515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6516     {
6517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6520         sw_if_index_set = 1;
6521       else if (unformat (i, "enable"))
6522         is_enable = 1;
6523       else if (unformat (i, "disable"))
6524         is_enable = 0;
6525       else
6526         break;
6527     }
6528
6529   if (sw_if_index_set == 0)
6530     {
6531       errmsg ("missing interface name or sw_if_index");
6532       return -99;
6533     }
6534
6535   /* Construct the API message */
6536   M (SW_INTERFACE_SET_VPATH, mp);
6537
6538   mp->sw_if_index = ntohl (sw_if_index);
6539   mp->enable = is_enable;
6540
6541   /* send it... */
6542   S (mp);
6543
6544   /* Wait for a reply... */
6545   W (ret);
6546   return ret;
6547 }
6548
6549 static int
6550 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6551 {
6552   unformat_input_t *i = vam->input;
6553   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6554   u32 sw_if_index = 0;
6555   u8 sw_if_index_set = 0;
6556   u8 is_enable = 1;
6557   u8 is_ipv6 = 0;
6558   int ret;
6559
6560   /* Parse args required to build the message */
6561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6562     {
6563       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6564         sw_if_index_set = 1;
6565       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6566         sw_if_index_set = 1;
6567       else if (unformat (i, "enable"))
6568         is_enable = 1;
6569       else if (unformat (i, "disable"))
6570         is_enable = 0;
6571       else if (unformat (i, "ip4"))
6572         is_ipv6 = 0;
6573       else if (unformat (i, "ip6"))
6574         is_ipv6 = 1;
6575       else
6576         break;
6577     }
6578
6579   if (sw_if_index_set == 0)
6580     {
6581       errmsg ("missing interface name or sw_if_index");
6582       return -99;
6583     }
6584
6585   /* Construct the API message */
6586   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6587
6588   mp->sw_if_index = ntohl (sw_if_index);
6589   mp->enable = is_enable;
6590   mp->is_ipv6 = is_ipv6;
6591
6592   /* send it... */
6593   S (mp);
6594
6595   /* Wait for a reply... */
6596   W (ret);
6597   return ret;
6598 }
6599
6600 static int
6601 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6602 {
6603   unformat_input_t *i = vam->input;
6604   vl_api_sw_interface_set_geneve_bypass_t *mp;
6605   u32 sw_if_index = 0;
6606   u8 sw_if_index_set = 0;
6607   u8 is_enable = 1;
6608   u8 is_ipv6 = 0;
6609   int ret;
6610
6611   /* Parse args required to build the message */
6612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6613     {
6614       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6615         sw_if_index_set = 1;
6616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6617         sw_if_index_set = 1;
6618       else if (unformat (i, "enable"))
6619         is_enable = 1;
6620       else if (unformat (i, "disable"))
6621         is_enable = 0;
6622       else if (unformat (i, "ip4"))
6623         is_ipv6 = 0;
6624       else if (unformat (i, "ip6"))
6625         is_ipv6 = 1;
6626       else
6627         break;
6628     }
6629
6630   if (sw_if_index_set == 0)
6631     {
6632       errmsg ("missing interface name or sw_if_index");
6633       return -99;
6634     }
6635
6636   /* Construct the API message */
6637   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6638
6639   mp->sw_if_index = ntohl (sw_if_index);
6640   mp->enable = is_enable;
6641   mp->is_ipv6 = is_ipv6;
6642
6643   /* send it... */
6644   S (mp);
6645
6646   /* Wait for a reply... */
6647   W (ret);
6648   return ret;
6649 }
6650
6651 static int
6652 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6653 {
6654   unformat_input_t *i = vam->input;
6655   vl_api_sw_interface_set_l2_xconnect_t *mp;
6656   u32 rx_sw_if_index;
6657   u8 rx_sw_if_index_set = 0;
6658   u32 tx_sw_if_index;
6659   u8 tx_sw_if_index_set = 0;
6660   u8 enable = 1;
6661   int ret;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6667         rx_sw_if_index_set = 1;
6668       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6669         tx_sw_if_index_set = 1;
6670       else if (unformat (i, "rx"))
6671         {
6672           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6673             {
6674               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6675                             &rx_sw_if_index))
6676                 rx_sw_if_index_set = 1;
6677             }
6678           else
6679             break;
6680         }
6681       else if (unformat (i, "tx"))
6682         {
6683           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6684             {
6685               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6686                             &tx_sw_if_index))
6687                 tx_sw_if_index_set = 1;
6688             }
6689           else
6690             break;
6691         }
6692       else if (unformat (i, "enable"))
6693         enable = 1;
6694       else if (unformat (i, "disable"))
6695         enable = 0;
6696       else
6697         break;
6698     }
6699
6700   if (rx_sw_if_index_set == 0)
6701     {
6702       errmsg ("missing rx interface name or rx_sw_if_index");
6703       return -99;
6704     }
6705
6706   if (enable && (tx_sw_if_index_set == 0))
6707     {
6708       errmsg ("missing tx interface name or tx_sw_if_index");
6709       return -99;
6710     }
6711
6712   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6713
6714   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6715   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6716   mp->enable = enable;
6717
6718   S (mp);
6719   W (ret);
6720   return ret;
6721 }
6722
6723 static int
6724 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6725 {
6726   unformat_input_t *i = vam->input;
6727   vl_api_sw_interface_set_l2_bridge_t *mp;
6728   u32 rx_sw_if_index;
6729   u8 rx_sw_if_index_set = 0;
6730   u32 bd_id;
6731   u8 bd_id_set = 0;
6732   u8 bvi = 0;
6733   u32 shg = 0;
6734   u8 enable = 1;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6741         rx_sw_if_index_set = 1;
6742       else if (unformat (i, "bd_id %d", &bd_id))
6743         bd_id_set = 1;
6744       else
6745         if (unformat
6746             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6747         rx_sw_if_index_set = 1;
6748       else if (unformat (i, "shg %d", &shg))
6749         ;
6750       else if (unformat (i, "bvi"))
6751         bvi = 1;
6752       else if (unformat (i, "enable"))
6753         enable = 1;
6754       else if (unformat (i, "disable"))
6755         enable = 0;
6756       else
6757         break;
6758     }
6759
6760   if (rx_sw_if_index_set == 0)
6761     {
6762       errmsg ("missing rx interface name or sw_if_index");
6763       return -99;
6764     }
6765
6766   if (enable && (bd_id_set == 0))
6767     {
6768       errmsg ("missing bridge domain");
6769       return -99;
6770     }
6771
6772   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6773
6774   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6775   mp->bd_id = ntohl (bd_id);
6776   mp->shg = (u8) shg;
6777   mp->bvi = bvi;
6778   mp->enable = enable;
6779
6780   S (mp);
6781   W (ret);
6782   return ret;
6783 }
6784
6785 static int
6786 api_bridge_domain_dump (vat_main_t * vam)
6787 {
6788   unformat_input_t *i = vam->input;
6789   vl_api_bridge_domain_dump_t *mp;
6790   vl_api_control_ping_t *mp_ping;
6791   u32 bd_id = ~0;
6792   int ret;
6793
6794   /* Parse args required to build the message */
6795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6796     {
6797       if (unformat (i, "bd_id %d", &bd_id))
6798         ;
6799       else
6800         break;
6801     }
6802
6803   M (BRIDGE_DOMAIN_DUMP, mp);
6804   mp->bd_id = ntohl (bd_id);
6805   S (mp);
6806
6807   /* Use a control ping for synchronization */
6808   MPING (CONTROL_PING, mp_ping);
6809   S (mp_ping);
6810
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_bridge_domain_add_del (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_bridge_domain_add_del_t *mp;
6820   u32 bd_id = ~0;
6821   u8 is_add = 1;
6822   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6823   u8 *bd_tag = NULL;
6824   u32 mac_age = 0;
6825   int ret;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "bd_id %d", &bd_id))
6831         ;
6832       else if (unformat (i, "flood %d", &flood))
6833         ;
6834       else if (unformat (i, "uu-flood %d", &uu_flood))
6835         ;
6836       else if (unformat (i, "forward %d", &forward))
6837         ;
6838       else if (unformat (i, "learn %d", &learn))
6839         ;
6840       else if (unformat (i, "arp-term %d", &arp_term))
6841         ;
6842       else if (unformat (i, "mac-age %d", &mac_age))
6843         ;
6844       else if (unformat (i, "bd-tag %s", &bd_tag))
6845         ;
6846       else if (unformat (i, "del"))
6847         {
6848           is_add = 0;
6849           flood = uu_flood = forward = learn = 0;
6850         }
6851       else
6852         break;
6853     }
6854
6855   if (bd_id == ~0)
6856     {
6857       errmsg ("missing bridge domain");
6858       ret = -99;
6859       goto done;
6860     }
6861
6862   if (mac_age > 255)
6863     {
6864       errmsg ("mac age must be less than 256 ");
6865       ret = -99;
6866       goto done;
6867     }
6868
6869   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6870     {
6871       errmsg ("bd-tag cannot be longer than 63");
6872       ret = -99;
6873       goto done;
6874     }
6875
6876   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6877
6878   mp->bd_id = ntohl (bd_id);
6879   mp->flood = flood;
6880   mp->uu_flood = uu_flood;
6881   mp->forward = forward;
6882   mp->learn = learn;
6883   mp->arp_term = arp_term;
6884   mp->is_add = is_add;
6885   mp->mac_age = (u8) mac_age;
6886   if (bd_tag)
6887     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6888
6889   S (mp);
6890   W (ret);
6891
6892 done:
6893   vec_free (bd_tag);
6894   return ret;
6895 }
6896
6897 static int
6898 api_l2fib_flush_bd (vat_main_t * vam)
6899 {
6900   unformat_input_t *i = vam->input;
6901   vl_api_l2fib_flush_bd_t *mp;
6902   u32 bd_id = ~0;
6903   int ret;
6904
6905   /* Parse args required to build the message */
6906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907     {
6908       if (unformat (i, "bd_id %d", &bd_id));
6909       else
6910         break;
6911     }
6912
6913   if (bd_id == ~0)
6914     {
6915       errmsg ("missing bridge domain");
6916       return -99;
6917     }
6918
6919   M (L2FIB_FLUSH_BD, mp);
6920
6921   mp->bd_id = htonl (bd_id);
6922
6923   S (mp);
6924   W (ret);
6925   return ret;
6926 }
6927
6928 static int
6929 api_l2fib_flush_int (vat_main_t * vam)
6930 {
6931   unformat_input_t *i = vam->input;
6932   vl_api_l2fib_flush_int_t *mp;
6933   u32 sw_if_index = ~0;
6934   int ret;
6935
6936   /* Parse args required to build the message */
6937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6938     {
6939       if (unformat (i, "sw_if_index %d", &sw_if_index));
6940       else
6941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6942       else
6943         break;
6944     }
6945
6946   if (sw_if_index == ~0)
6947     {
6948       errmsg ("missing interface name or sw_if_index");
6949       return -99;
6950     }
6951
6952   M (L2FIB_FLUSH_INT, mp);
6953
6954   mp->sw_if_index = ntohl (sw_if_index);
6955
6956   S (mp);
6957   W (ret);
6958   return ret;
6959 }
6960
6961 static int
6962 api_l2fib_add_del (vat_main_t * vam)
6963 {
6964   unformat_input_t *i = vam->input;
6965   vl_api_l2fib_add_del_t *mp;
6966   f64 timeout;
6967   u64 mac = 0;
6968   u8 mac_set = 0;
6969   u32 bd_id;
6970   u8 bd_id_set = 0;
6971   u32 sw_if_index = ~0;
6972   u8 sw_if_index_set = 0;
6973   u8 is_add = 1;
6974   u8 static_mac = 0;
6975   u8 filter_mac = 0;
6976   u8 bvi_mac = 0;
6977   int count = 1;
6978   f64 before = 0;
6979   int j;
6980
6981   /* Parse args required to build the message */
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6985         mac_set = 1;
6986       else if (unformat (i, "bd_id %d", &bd_id))
6987         bd_id_set = 1;
6988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6989         sw_if_index_set = 1;
6990       else if (unformat (i, "sw_if"))
6991         {
6992           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993             {
6994               if (unformat
6995                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6996                 sw_if_index_set = 1;
6997             }
6998           else
6999             break;
7000         }
7001       else if (unformat (i, "static"))
7002         static_mac = 1;
7003       else if (unformat (i, "filter"))
7004         {
7005           filter_mac = 1;
7006           static_mac = 1;
7007         }
7008       else if (unformat (i, "bvi"))
7009         {
7010           bvi_mac = 1;
7011           static_mac = 1;
7012         }
7013       else if (unformat (i, "del"))
7014         is_add = 0;
7015       else if (unformat (i, "count %d", &count))
7016         ;
7017       else
7018         break;
7019     }
7020
7021   if (mac_set == 0)
7022     {
7023       errmsg ("missing mac address");
7024       return -99;
7025     }
7026
7027   if (bd_id_set == 0)
7028     {
7029       errmsg ("missing bridge domain");
7030       return -99;
7031     }
7032
7033   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7034     {
7035       errmsg ("missing interface name or sw_if_index");
7036       return -99;
7037     }
7038
7039   if (count > 1)
7040     {
7041       /* Turn on async mode */
7042       vam->async_mode = 1;
7043       vam->async_errors = 0;
7044       before = vat_time_now (vam);
7045     }
7046
7047   for (j = 0; j < count; j++)
7048     {
7049       M (L2FIB_ADD_DEL, mp);
7050
7051       mp->mac = mac;
7052       mp->bd_id = ntohl (bd_id);
7053       mp->is_add = is_add;
7054
7055       if (is_add)
7056         {
7057           mp->sw_if_index = ntohl (sw_if_index);
7058           mp->static_mac = static_mac;
7059           mp->filter_mac = filter_mac;
7060           mp->bvi_mac = bvi_mac;
7061         }
7062       increment_mac_address (&mac);
7063       /* send it... */
7064       S (mp);
7065     }
7066
7067   if (count > 1)
7068     {
7069       vl_api_control_ping_t *mp_ping;
7070       f64 after;
7071
7072       /* Shut off async mode */
7073       vam->async_mode = 0;
7074
7075       MPING (CONTROL_PING, mp_ping);
7076       S (mp_ping);
7077
7078       timeout = vat_time_now (vam) + 1.0;
7079       while (vat_time_now (vam) < timeout)
7080         if (vam->result_ready == 1)
7081           goto out;
7082       vam->retval = -99;
7083
7084     out:
7085       if (vam->retval == -99)
7086         errmsg ("timeout");
7087
7088       if (vam->async_errors > 0)
7089         {
7090           errmsg ("%d asynchronous errors", vam->async_errors);
7091           vam->retval = -98;
7092         }
7093       vam->async_errors = 0;
7094       after = vat_time_now (vam);
7095
7096       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7097              count, after - before, count / (after - before));
7098     }
7099   else
7100     {
7101       int ret;
7102
7103       /* Wait for a reply... */
7104       W (ret);
7105       return ret;
7106     }
7107   /* Return the good/bad news */
7108   return (vam->retval);
7109 }
7110
7111 static int
7112 api_bridge_domain_set_mac_age (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_bridge_domain_set_mac_age_t *mp;
7116   u32 bd_id = ~0;
7117   u32 mac_age = 0;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "bd_id %d", &bd_id));
7124       else if (unformat (i, "mac-age %d", &mac_age));
7125       else
7126         break;
7127     }
7128
7129   if (bd_id == ~0)
7130     {
7131       errmsg ("missing bridge domain");
7132       return -99;
7133     }
7134
7135   if (mac_age > 255)
7136     {
7137       errmsg ("mac age must be less than 256 ");
7138       return -99;
7139     }
7140
7141   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7142
7143   mp->bd_id = htonl (bd_id);
7144   mp->mac_age = (u8) mac_age;
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2_flags (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2_flags_t *mp;
7156   u32 sw_if_index;
7157   u32 flags = 0;
7158   u8 sw_if_index_set = 0;
7159   u8 is_set = 0;
7160   int ret;
7161
7162   /* Parse args required to build the message */
7163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7164     {
7165       if (unformat (i, "sw_if_index %d", &sw_if_index))
7166         sw_if_index_set = 1;
7167       else if (unformat (i, "sw_if"))
7168         {
7169           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7170             {
7171               if (unformat
7172                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7173                 sw_if_index_set = 1;
7174             }
7175           else
7176             break;
7177         }
7178       else if (unformat (i, "learn"))
7179         flags |= L2_LEARN;
7180       else if (unformat (i, "forward"))
7181         flags |= L2_FWD;
7182       else if (unformat (i, "flood"))
7183         flags |= L2_FLOOD;
7184       else if (unformat (i, "uu-flood"))
7185         flags |= L2_UU_FLOOD;
7186       else if (unformat (i, "arp-term"))
7187         flags |= L2_ARP_TERM;
7188       else if (unformat (i, "off"))
7189         is_set = 0;
7190       else if (unformat (i, "disable"))
7191         is_set = 0;
7192       else
7193         break;
7194     }
7195
7196   if (sw_if_index_set == 0)
7197     {
7198       errmsg ("missing interface name or sw_if_index");
7199       return -99;
7200     }
7201
7202   M (L2_FLAGS, mp);
7203
7204   mp->sw_if_index = ntohl (sw_if_index);
7205   mp->feature_bitmap = ntohl (flags);
7206   mp->is_set = is_set;
7207
7208   S (mp);
7209   W (ret);
7210   return ret;
7211 }
7212
7213 static int
7214 api_bridge_flags (vat_main_t * vam)
7215 {
7216   unformat_input_t *i = vam->input;
7217   vl_api_bridge_flags_t *mp;
7218   u32 bd_id;
7219   u8 bd_id_set = 0;
7220   u8 is_set = 1;
7221   u32 flags = 0;
7222   int ret;
7223
7224   /* Parse args required to build the message */
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "bd_id %d", &bd_id))
7228         bd_id_set = 1;
7229       else if (unformat (i, "learn"))
7230         flags |= L2_LEARN;
7231       else if (unformat (i, "forward"))
7232         flags |= L2_FWD;
7233       else if (unformat (i, "flood"))
7234         flags |= L2_FLOOD;
7235       else if (unformat (i, "uu-flood"))
7236         flags |= L2_UU_FLOOD;
7237       else if (unformat (i, "arp-term"))
7238         flags |= L2_ARP_TERM;
7239       else if (unformat (i, "off"))
7240         is_set = 0;
7241       else if (unformat (i, "disable"))
7242         is_set = 0;
7243       else
7244         break;
7245     }
7246
7247   if (bd_id_set == 0)
7248     {
7249       errmsg ("missing bridge domain");
7250       return -99;
7251     }
7252
7253   M (BRIDGE_FLAGS, mp);
7254
7255   mp->bd_id = ntohl (bd_id);
7256   mp->feature_bitmap = ntohl (flags);
7257   mp->is_set = is_set;
7258
7259   S (mp);
7260   W (ret);
7261   return ret;
7262 }
7263
7264 static int
7265 api_bd_ip_mac_add_del (vat_main_t * vam)
7266 {
7267   unformat_input_t *i = vam->input;
7268   vl_api_bd_ip_mac_add_del_t *mp;
7269   u32 bd_id;
7270   u8 is_ipv6 = 0;
7271   u8 is_add = 1;
7272   u8 bd_id_set = 0;
7273   u8 ip_set = 0;
7274   u8 mac_set = 0;
7275   ip4_address_t v4addr;
7276   ip6_address_t v6addr;
7277   u8 macaddr[6];
7278   int ret;
7279
7280
7281   /* Parse args required to build the message */
7282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7283     {
7284       if (unformat (i, "bd_id %d", &bd_id))
7285         {
7286           bd_id_set++;
7287         }
7288       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7289         {
7290           ip_set++;
7291         }
7292       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7293         {
7294           ip_set++;
7295           is_ipv6++;
7296         }
7297       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7298         {
7299           mac_set++;
7300         }
7301       else if (unformat (i, "del"))
7302         is_add = 0;
7303       else
7304         break;
7305     }
7306
7307   if (bd_id_set == 0)
7308     {
7309       errmsg ("missing bridge domain");
7310       return -99;
7311     }
7312   else if (ip_set == 0)
7313     {
7314       errmsg ("missing IP address");
7315       return -99;
7316     }
7317   else if (mac_set == 0)
7318     {
7319       errmsg ("missing MAC address");
7320       return -99;
7321     }
7322
7323   M (BD_IP_MAC_ADD_DEL, mp);
7324
7325   mp->bd_id = ntohl (bd_id);
7326   mp->is_ipv6 = is_ipv6;
7327   mp->is_add = is_add;
7328   if (is_ipv6)
7329     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7330   else
7331     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7332   clib_memcpy (mp->mac_address, macaddr, 6);
7333   S (mp);
7334   W (ret);
7335   return ret;
7336 }
7337
7338 static int
7339 api_tap_connect (vat_main_t * vam)
7340 {
7341   unformat_input_t *i = vam->input;
7342   vl_api_tap_connect_t *mp;
7343   u8 mac_address[6];
7344   u8 random_mac = 1;
7345   u8 name_set = 0;
7346   u8 *tap_name;
7347   u8 *tag = 0;
7348   ip4_address_t ip4_address;
7349   u32 ip4_mask_width;
7350   int ip4_address_set = 0;
7351   ip6_address_t ip6_address;
7352   u32 ip6_mask_width;
7353   int ip6_address_set = 0;
7354   int ret;
7355
7356   memset (mac_address, 0, sizeof (mac_address));
7357
7358   /* Parse args required to build the message */
7359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7360     {
7361       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7362         {
7363           random_mac = 0;
7364         }
7365       else if (unformat (i, "random-mac"))
7366         random_mac = 1;
7367       else if (unformat (i, "tapname %s", &tap_name))
7368         name_set = 1;
7369       else if (unformat (i, "tag %s", &tag))
7370         ;
7371       else if (unformat (i, "address %U/%d",
7372                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7373         ip4_address_set = 1;
7374       else if (unformat (i, "address %U/%d",
7375                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7376         ip6_address_set = 1;
7377       else
7378         break;
7379     }
7380
7381   if (name_set == 0)
7382     {
7383       errmsg ("missing tap name");
7384       return -99;
7385     }
7386   if (vec_len (tap_name) > 63)
7387     {
7388       errmsg ("tap name too long");
7389       return -99;
7390     }
7391   vec_add1 (tap_name, 0);
7392
7393   if (vec_len (tag) > 63)
7394     {
7395       errmsg ("tag too long");
7396       return -99;
7397     }
7398
7399   /* Construct the API message */
7400   M (TAP_CONNECT, mp);
7401
7402   mp->use_random_mac = random_mac;
7403   clib_memcpy (mp->mac_address, mac_address, 6);
7404   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7405   if (tag)
7406     clib_memcpy (mp->tag, tag, vec_len (tag));
7407
7408   if (ip4_address_set)
7409     {
7410       mp->ip4_address_set = 1;
7411       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7412       mp->ip4_mask_width = ip4_mask_width;
7413     }
7414   if (ip6_address_set)
7415     {
7416       mp->ip6_address_set = 1;
7417       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7418       mp->ip6_mask_width = ip6_mask_width;
7419     }
7420
7421   vec_free (tap_name);
7422   vec_free (tag);
7423
7424   /* send it... */
7425   S (mp);
7426
7427   /* Wait for a reply... */
7428   W (ret);
7429   return ret;
7430 }
7431
7432 static int
7433 api_tap_modify (vat_main_t * vam)
7434 {
7435   unformat_input_t *i = vam->input;
7436   vl_api_tap_modify_t *mp;
7437   u8 mac_address[6];
7438   u8 random_mac = 1;
7439   u8 name_set = 0;
7440   u8 *tap_name;
7441   u32 sw_if_index = ~0;
7442   u8 sw_if_index_set = 0;
7443   int ret;
7444
7445   memset (mac_address, 0, sizeof (mac_address));
7446
7447   /* Parse args required to build the message */
7448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7451         sw_if_index_set = 1;
7452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7453         sw_if_index_set = 1;
7454       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7455         {
7456           random_mac = 0;
7457         }
7458       else if (unformat (i, "random-mac"))
7459         random_mac = 1;
7460       else if (unformat (i, "tapname %s", &tap_name))
7461         name_set = 1;
7462       else
7463         break;
7464     }
7465
7466   if (sw_if_index_set == 0)
7467     {
7468       errmsg ("missing vpp interface name");
7469       return -99;
7470     }
7471   if (name_set == 0)
7472     {
7473       errmsg ("missing tap name");
7474       return -99;
7475     }
7476   if (vec_len (tap_name) > 63)
7477     {
7478       errmsg ("tap name too long");
7479     }
7480   vec_add1 (tap_name, 0);
7481
7482   /* Construct the API message */
7483   M (TAP_MODIFY, mp);
7484
7485   mp->use_random_mac = random_mac;
7486   mp->sw_if_index = ntohl (sw_if_index);
7487   clib_memcpy (mp->mac_address, mac_address, 6);
7488   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7489   vec_free (tap_name);
7490
7491   /* send it... */
7492   S (mp);
7493
7494   /* Wait for a reply... */
7495   W (ret);
7496   return ret;
7497 }
7498
7499 static int
7500 api_tap_delete (vat_main_t * vam)
7501 {
7502   unformat_input_t *i = vam->input;
7503   vl_api_tap_delete_t *mp;
7504   u32 sw_if_index = ~0;
7505   u8 sw_if_index_set = 0;
7506   int ret;
7507
7508   /* Parse args required to build the message */
7509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7510     {
7511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7512         sw_if_index_set = 1;
7513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7514         sw_if_index_set = 1;
7515       else
7516         break;
7517     }
7518
7519   if (sw_if_index_set == 0)
7520     {
7521       errmsg ("missing vpp interface name");
7522       return -99;
7523     }
7524
7525   /* Construct the API message */
7526   M (TAP_DELETE, mp);
7527
7528   mp->sw_if_index = ntohl (sw_if_index);
7529
7530   /* send it... */
7531   S (mp);
7532
7533   /* Wait for a reply... */
7534   W (ret);
7535   return ret;
7536 }
7537
7538 static int
7539 api_ip_table_add_del (vat_main_t * vam)
7540 {
7541   unformat_input_t *i = vam->input;
7542   vl_api_ip_table_add_del_t *mp;
7543   u32 table_id = ~0;
7544   u8 is_ipv6 = 0;
7545   u8 is_add = 1;
7546   int ret = 0;
7547
7548   /* Parse args required to build the message */
7549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550     {
7551       if (unformat (i, "ipv6"))
7552         is_ipv6 = 1;
7553       else if (unformat (i, "del"))
7554         is_add = 0;
7555       else if (unformat (i, "add"))
7556         is_add = 1;
7557       else if (unformat (i, "table %d", &table_id))
7558         ;
7559       else
7560         {
7561           clib_warning ("parse error '%U'", format_unformat_error, i);
7562           return -99;
7563         }
7564     }
7565
7566   if (~0 == table_id)
7567     {
7568       errmsg ("missing table-ID");
7569       return -99;
7570     }
7571
7572   /* Construct the API message */
7573   M (IP_TABLE_ADD_DEL, mp);
7574
7575   mp->table_id = ntohl (table_id);
7576   mp->is_ipv6 = is_ipv6;
7577   mp->is_add = is_add;
7578
7579   /* send it... */
7580   S (mp);
7581
7582   /* Wait for a reply... */
7583   W (ret);
7584
7585   return ret;
7586 }
7587
7588 static int
7589 api_ip_add_del_route (vat_main_t * vam)
7590 {
7591   unformat_input_t *i = vam->input;
7592   vl_api_ip_add_del_route_t *mp;
7593   u32 sw_if_index = ~0, vrf_id = 0;
7594   u8 is_ipv6 = 0;
7595   u8 is_local = 0, is_drop = 0;
7596   u8 is_unreach = 0, is_prohibit = 0;
7597   u8 create_vrf_if_needed = 0;
7598   u8 is_add = 1;
7599   u32 next_hop_weight = 1;
7600   u8 is_multipath = 0;
7601   u8 address_set = 0;
7602   u8 address_length_set = 0;
7603   u32 next_hop_table_id = 0;
7604   u32 resolve_attempts = 0;
7605   u32 dst_address_length = 0;
7606   u8 next_hop_set = 0;
7607   ip4_address_t v4_dst_address, v4_next_hop_address;
7608   ip6_address_t v6_dst_address, v6_next_hop_address;
7609   int count = 1;
7610   int j;
7611   f64 before = 0;
7612   u32 random_add_del = 0;
7613   u32 *random_vector = 0;
7614   uword *random_hash;
7615   u32 random_seed = 0xdeaddabe;
7616   u32 classify_table_index = ~0;
7617   u8 is_classify = 0;
7618   u8 resolve_host = 0, resolve_attached = 0;
7619   mpls_label_t *next_hop_out_label_stack = NULL;
7620   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7621   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         ;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         ;
7630       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7631         {
7632           address_set = 1;
7633           is_ipv6 = 0;
7634         }
7635       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7636         {
7637           address_set = 1;
7638           is_ipv6 = 1;
7639         }
7640       else if (unformat (i, "/%d", &dst_address_length))
7641         {
7642           address_length_set = 1;
7643         }
7644
7645       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7646                                          &v4_next_hop_address))
7647         {
7648           next_hop_set = 1;
7649         }
7650       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7651                                          &v6_next_hop_address))
7652         {
7653           next_hop_set = 1;
7654         }
7655       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7656         ;
7657       else if (unformat (i, "weight %d", &next_hop_weight))
7658         ;
7659       else if (unformat (i, "drop"))
7660         {
7661           is_drop = 1;
7662         }
7663       else if (unformat (i, "null-send-unreach"))
7664         {
7665           is_unreach = 1;
7666         }
7667       else if (unformat (i, "null-send-prohibit"))
7668         {
7669           is_prohibit = 1;
7670         }
7671       else if (unformat (i, "local"))
7672         {
7673           is_local = 1;
7674         }
7675       else if (unformat (i, "classify %d", &classify_table_index))
7676         {
7677           is_classify = 1;
7678         }
7679       else if (unformat (i, "del"))
7680         is_add = 0;
7681       else if (unformat (i, "add"))
7682         is_add = 1;
7683       else if (unformat (i, "resolve-via-host"))
7684         resolve_host = 1;
7685       else if (unformat (i, "resolve-via-attached"))
7686         resolve_attached = 1;
7687       else if (unformat (i, "multipath"))
7688         is_multipath = 1;
7689       else if (unformat (i, "vrf %d", &vrf_id))
7690         ;
7691       else if (unformat (i, "create-vrf"))
7692         create_vrf_if_needed = 1;
7693       else if (unformat (i, "count %d", &count))
7694         ;
7695       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7696         ;
7697       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7698         ;
7699       else if (unformat (i, "out-label %d", &next_hop_out_label))
7700         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7701       else if (unformat (i, "via-label %d", &next_hop_via_label))
7702         ;
7703       else if (unformat (i, "random"))
7704         random_add_del = 1;
7705       else if (unformat (i, "seed %d", &random_seed))
7706         ;
7707       else
7708         {
7709           clib_warning ("parse error '%U'", format_unformat_error, i);
7710           return -99;
7711         }
7712     }
7713
7714   if (!next_hop_set && !is_drop && !is_local &&
7715       !is_classify && !is_unreach && !is_prohibit &&
7716       MPLS_LABEL_INVALID == next_hop_via_label)
7717     {
7718       errmsg
7719         ("next hop / local / drop / unreach / prohibit / classify not set");
7720       return -99;
7721     }
7722
7723   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7724     {
7725       errmsg ("next hop and next-hop via label set");
7726       return -99;
7727     }
7728   if (address_set == 0)
7729     {
7730       errmsg ("missing addresses");
7731       return -99;
7732     }
7733
7734   if (address_length_set == 0)
7735     {
7736       errmsg ("missing address length");
7737       return -99;
7738     }
7739
7740   /* Generate a pile of unique, random routes */
7741   if (random_add_del)
7742     {
7743       u32 this_random_address;
7744       random_hash = hash_create (count, sizeof (uword));
7745
7746       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7747       for (j = 0; j <= count; j++)
7748         {
7749           do
7750             {
7751               this_random_address = random_u32 (&random_seed);
7752               this_random_address =
7753                 clib_host_to_net_u32 (this_random_address);
7754             }
7755           while (hash_get (random_hash, this_random_address));
7756           vec_add1 (random_vector, this_random_address);
7757           hash_set (random_hash, this_random_address, 1);
7758         }
7759       hash_free (random_hash);
7760       v4_dst_address.as_u32 = random_vector[0];
7761     }
7762
7763   if (count > 1)
7764     {
7765       /* Turn on async mode */
7766       vam->async_mode = 1;
7767       vam->async_errors = 0;
7768       before = vat_time_now (vam);
7769     }
7770
7771   for (j = 0; j < count; j++)
7772     {
7773       /* Construct the API message */
7774       M2 (IP_ADD_DEL_ROUTE, mp,
7775           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7776
7777       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7778       mp->table_id = ntohl (vrf_id);
7779       mp->create_vrf_if_needed = create_vrf_if_needed;
7780
7781       mp->is_add = is_add;
7782       mp->is_drop = is_drop;
7783       mp->is_unreach = is_unreach;
7784       mp->is_prohibit = is_prohibit;
7785       mp->is_ipv6 = is_ipv6;
7786       mp->is_local = is_local;
7787       mp->is_classify = is_classify;
7788       mp->is_multipath = is_multipath;
7789       mp->is_resolve_host = resolve_host;
7790       mp->is_resolve_attached = resolve_attached;
7791       mp->next_hop_weight = next_hop_weight;
7792       mp->dst_address_length = dst_address_length;
7793       mp->next_hop_table_id = ntohl (next_hop_table_id);
7794       mp->classify_table_index = ntohl (classify_table_index);
7795       mp->next_hop_via_label = ntohl (next_hop_via_label);
7796       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7797       if (0 != mp->next_hop_n_out_labels)
7798         {
7799           memcpy (mp->next_hop_out_label_stack,
7800                   next_hop_out_label_stack,
7801                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7802           vec_free (next_hop_out_label_stack);
7803         }
7804
7805       if (is_ipv6)
7806         {
7807           clib_memcpy (mp->dst_address, &v6_dst_address,
7808                        sizeof (v6_dst_address));
7809           if (next_hop_set)
7810             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7811                          sizeof (v6_next_hop_address));
7812           increment_v6_address (&v6_dst_address);
7813         }
7814       else
7815         {
7816           clib_memcpy (mp->dst_address, &v4_dst_address,
7817                        sizeof (v4_dst_address));
7818           if (next_hop_set)
7819             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7820                          sizeof (v4_next_hop_address));
7821           if (random_add_del)
7822             v4_dst_address.as_u32 = random_vector[j + 1];
7823           else
7824             increment_v4_address (&v4_dst_address);
7825         }
7826       /* send it... */
7827       S (mp);
7828       /* If we receive SIGTERM, stop now... */
7829       if (vam->do_exit)
7830         break;
7831     }
7832
7833   /* When testing multiple add/del ops, use a control-ping to sync */
7834   if (count > 1)
7835     {
7836       vl_api_control_ping_t *mp_ping;
7837       f64 after;
7838       f64 timeout;
7839
7840       /* Shut off async mode */
7841       vam->async_mode = 0;
7842
7843       MPING (CONTROL_PING, mp_ping);
7844       S (mp_ping);
7845
7846       timeout = vat_time_now (vam) + 1.0;
7847       while (vat_time_now (vam) < timeout)
7848         if (vam->result_ready == 1)
7849           goto out;
7850       vam->retval = -99;
7851
7852     out:
7853       if (vam->retval == -99)
7854         errmsg ("timeout");
7855
7856       if (vam->async_errors > 0)
7857         {
7858           errmsg ("%d asynchronous errors", vam->async_errors);
7859           vam->retval = -98;
7860         }
7861       vam->async_errors = 0;
7862       after = vat_time_now (vam);
7863
7864       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7865       if (j > 0)
7866         count = j;
7867
7868       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7869              count, after - before, count / (after - before));
7870     }
7871   else
7872     {
7873       int ret;
7874
7875       /* Wait for a reply... */
7876       W (ret);
7877       return ret;
7878     }
7879
7880   /* Return the good/bad news */
7881   return (vam->retval);
7882 }
7883
7884 static int
7885 api_ip_mroute_add_del (vat_main_t * vam)
7886 {
7887   unformat_input_t *i = vam->input;
7888   vl_api_ip_mroute_add_del_t *mp;
7889   u32 sw_if_index = ~0, vrf_id = 0;
7890   u8 is_ipv6 = 0;
7891   u8 is_local = 0;
7892   u8 create_vrf_if_needed = 0;
7893   u8 is_add = 1;
7894   u8 address_set = 0;
7895   u32 grp_address_length = 0;
7896   ip4_address_t v4_grp_address, v4_src_address;
7897   ip6_address_t v6_grp_address, v6_src_address;
7898   mfib_itf_flags_t iflags = 0;
7899   mfib_entry_flags_t eflags = 0;
7900   int ret;
7901
7902   /* Parse args required to build the message */
7903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7904     {
7905       if (unformat (i, "sw_if_index %d", &sw_if_index))
7906         ;
7907       else if (unformat (i, "%U %U",
7908                          unformat_ip4_address, &v4_src_address,
7909                          unformat_ip4_address, &v4_grp_address))
7910         {
7911           grp_address_length = 64;
7912           address_set = 1;
7913           is_ipv6 = 0;
7914         }
7915       else if (unformat (i, "%U %U",
7916                          unformat_ip6_address, &v6_src_address,
7917                          unformat_ip6_address, &v6_grp_address))
7918         {
7919           grp_address_length = 256;
7920           address_set = 1;
7921           is_ipv6 = 1;
7922         }
7923       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7924         {
7925           memset (&v4_src_address, 0, sizeof (v4_src_address));
7926           grp_address_length = 32;
7927           address_set = 1;
7928           is_ipv6 = 0;
7929         }
7930       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7931         {
7932           memset (&v6_src_address, 0, sizeof (v6_src_address));
7933           grp_address_length = 128;
7934           address_set = 1;
7935           is_ipv6 = 1;
7936         }
7937       else if (unformat (i, "/%d", &grp_address_length))
7938         ;
7939       else if (unformat (i, "local"))
7940         {
7941           is_local = 1;
7942         }
7943       else if (unformat (i, "del"))
7944         is_add = 0;
7945       else if (unformat (i, "add"))
7946         is_add = 1;
7947       else if (unformat (i, "vrf %d", &vrf_id))
7948         ;
7949       else if (unformat (i, "create-vrf"))
7950         create_vrf_if_needed = 1;
7951       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7952         ;
7953       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7954         ;
7955       else
7956         {
7957           clib_warning ("parse error '%U'", format_unformat_error, i);
7958           return -99;
7959         }
7960     }
7961
7962   if (address_set == 0)
7963     {
7964       errmsg ("missing addresses\n");
7965       return -99;
7966     }
7967
7968   /* Construct the API message */
7969   M (IP_MROUTE_ADD_DEL, mp);
7970
7971   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7972   mp->table_id = ntohl (vrf_id);
7973   mp->create_vrf_if_needed = create_vrf_if_needed;
7974
7975   mp->is_add = is_add;
7976   mp->is_ipv6 = is_ipv6;
7977   mp->is_local = is_local;
7978   mp->itf_flags = ntohl (iflags);
7979   mp->entry_flags = ntohl (eflags);
7980   mp->grp_address_length = grp_address_length;
7981   mp->grp_address_length = ntohs (mp->grp_address_length);
7982
7983   if (is_ipv6)
7984     {
7985       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7986       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7987     }
7988   else
7989     {
7990       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7991       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7992
7993     }
7994
7995   /* send it... */
7996   S (mp);
7997   /* Wait for a reply... */
7998   W (ret);
7999   return ret;
8000 }
8001
8002 static int
8003 api_mpls_table_add_del (vat_main_t * vam)
8004 {
8005   unformat_input_t *i = vam->input;
8006   vl_api_mpls_table_add_del_t *mp;
8007   u32 table_id = ~0;
8008   u8 is_add = 1;
8009   int ret = 0;
8010
8011   /* Parse args required to build the message */
8012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8013     {
8014       if (unformat (i, "table %d", &table_id))
8015         ;
8016       else if (unformat (i, "del"))
8017         is_add = 0;
8018       else if (unformat (i, "add"))
8019         is_add = 1;
8020       else
8021         {
8022           clib_warning ("parse error '%U'", format_unformat_error, i);
8023           return -99;
8024         }
8025     }
8026
8027   if (~0 == table_id)
8028     {
8029       errmsg ("missing table-ID");
8030       return -99;
8031     }
8032
8033   /* Construct the API message */
8034   M (MPLS_TABLE_ADD_DEL, mp);
8035
8036   mp->mt_table_id = ntohl (table_id);
8037   mp->mt_is_add = is_add;
8038
8039   /* send it... */
8040   S (mp);
8041
8042   /* Wait for a reply... */
8043   W (ret);
8044
8045   return ret;
8046 }
8047
8048 static int
8049 api_mpls_route_add_del (vat_main_t * vam)
8050 {
8051   unformat_input_t *i = vam->input;
8052   vl_api_mpls_route_add_del_t *mp;
8053   u32 sw_if_index = ~0, table_id = 0;
8054   u8 create_table_if_needed = 0;
8055   u8 is_add = 1;
8056   u32 next_hop_weight = 1;
8057   u8 is_multipath = 0;
8058   u32 next_hop_table_id = 0;
8059   u8 next_hop_set = 0;
8060   ip4_address_t v4_next_hop_address = {
8061     .as_u32 = 0,
8062   };
8063   ip6_address_t v6_next_hop_address = { {0} };
8064   int count = 1;
8065   int j;
8066   f64 before = 0;
8067   u32 classify_table_index = ~0;
8068   u8 is_classify = 0;
8069   u8 resolve_host = 0, resolve_attached = 0;
8070   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8071   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8072   mpls_label_t *next_hop_out_label_stack = NULL;
8073   mpls_label_t local_label = MPLS_LABEL_INVALID;
8074   u8 is_eos = 0;
8075   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8076
8077   /* Parse args required to build the message */
8078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8079     {
8080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8081         ;
8082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8083         ;
8084       else if (unformat (i, "%d", &local_label))
8085         ;
8086       else if (unformat (i, "eos"))
8087         is_eos = 1;
8088       else if (unformat (i, "non-eos"))
8089         is_eos = 0;
8090       else if (unformat (i, "via %U", unformat_ip4_address,
8091                          &v4_next_hop_address))
8092         {
8093           next_hop_set = 1;
8094           next_hop_proto = DPO_PROTO_IP4;
8095         }
8096       else if (unformat (i, "via %U", unformat_ip6_address,
8097                          &v6_next_hop_address))
8098         {
8099           next_hop_set = 1;
8100           next_hop_proto = DPO_PROTO_IP6;
8101         }
8102       else if (unformat (i, "weight %d", &next_hop_weight))
8103         ;
8104       else if (unformat (i, "create-table"))
8105         create_table_if_needed = 1;
8106       else if (unformat (i, "classify %d", &classify_table_index))
8107         {
8108           is_classify = 1;
8109         }
8110       else if (unformat (i, "del"))
8111         is_add = 0;
8112       else if (unformat (i, "add"))
8113         is_add = 1;
8114       else if (unformat (i, "resolve-via-host"))
8115         resolve_host = 1;
8116       else if (unformat (i, "resolve-via-attached"))
8117         resolve_attached = 1;
8118       else if (unformat (i, "multipath"))
8119         is_multipath = 1;
8120       else if (unformat (i, "count %d", &count))
8121         ;
8122       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8123         {
8124           next_hop_set = 1;
8125           next_hop_proto = DPO_PROTO_IP4;
8126         }
8127       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8128         {
8129           next_hop_set = 1;
8130           next_hop_proto = DPO_PROTO_IP6;
8131         }
8132       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8133         ;
8134       else if (unformat (i, "via-label %d", &next_hop_via_label))
8135         ;
8136       else if (unformat (i, "out-label %d", &next_hop_out_label))
8137         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8138       else
8139         {
8140           clib_warning ("parse error '%U'", format_unformat_error, i);
8141           return -99;
8142         }
8143     }
8144
8145   if (!next_hop_set && !is_classify)
8146     {
8147       errmsg ("next hop / classify not set");
8148       return -99;
8149     }
8150
8151   if (MPLS_LABEL_INVALID == local_label)
8152     {
8153       errmsg ("missing label");
8154       return -99;
8155     }
8156
8157   if (count > 1)
8158     {
8159       /* Turn on async mode */
8160       vam->async_mode = 1;
8161       vam->async_errors = 0;
8162       before = vat_time_now (vam);
8163     }
8164
8165   for (j = 0; j < count; j++)
8166     {
8167       /* Construct the API message */
8168       M2 (MPLS_ROUTE_ADD_DEL, mp,
8169           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8170
8171       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8172       mp->mr_table_id = ntohl (table_id);
8173       mp->mr_create_table_if_needed = create_table_if_needed;
8174
8175       mp->mr_is_add = is_add;
8176       mp->mr_next_hop_proto = next_hop_proto;
8177       mp->mr_is_classify = is_classify;
8178       mp->mr_is_multipath = is_multipath;
8179       mp->mr_is_resolve_host = resolve_host;
8180       mp->mr_is_resolve_attached = resolve_attached;
8181       mp->mr_next_hop_weight = next_hop_weight;
8182       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8183       mp->mr_classify_table_index = ntohl (classify_table_index);
8184       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8185       mp->mr_label = ntohl (local_label);
8186       mp->mr_eos = is_eos;
8187
8188       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8189       if (0 != mp->mr_next_hop_n_out_labels)
8190         {
8191           memcpy (mp->mr_next_hop_out_label_stack,
8192                   next_hop_out_label_stack,
8193                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8194           vec_free (next_hop_out_label_stack);
8195         }
8196
8197       if (next_hop_set)
8198         {
8199           if (DPO_PROTO_IP4 == next_hop_proto)
8200             {
8201               clib_memcpy (mp->mr_next_hop,
8202                            &v4_next_hop_address,
8203                            sizeof (v4_next_hop_address));
8204             }
8205           else if (DPO_PROTO_IP6 == next_hop_proto)
8206
8207             {
8208               clib_memcpy (mp->mr_next_hop,
8209                            &v6_next_hop_address,
8210                            sizeof (v6_next_hop_address));
8211             }
8212         }
8213       local_label++;
8214
8215       /* send it... */
8216       S (mp);
8217       /* If we receive SIGTERM, stop now... */
8218       if (vam->do_exit)
8219         break;
8220     }
8221
8222   /* When testing multiple add/del ops, use a control-ping to sync */
8223   if (count > 1)
8224     {
8225       vl_api_control_ping_t *mp_ping;
8226       f64 after;
8227       f64 timeout;
8228
8229       /* Shut off async mode */
8230       vam->async_mode = 0;
8231
8232       MPING (CONTROL_PING, mp_ping);
8233       S (mp_ping);
8234
8235       timeout = vat_time_now (vam) + 1.0;
8236       while (vat_time_now (vam) < timeout)
8237         if (vam->result_ready == 1)
8238           goto out;
8239       vam->retval = -99;
8240
8241     out:
8242       if (vam->retval == -99)
8243         errmsg ("timeout");
8244
8245       if (vam->async_errors > 0)
8246         {
8247           errmsg ("%d asynchronous errors", vam->async_errors);
8248           vam->retval = -98;
8249         }
8250       vam->async_errors = 0;
8251       after = vat_time_now (vam);
8252
8253       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8254       if (j > 0)
8255         count = j;
8256
8257       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8258              count, after - before, count / (after - before));
8259     }
8260   else
8261     {
8262       int ret;
8263
8264       /* Wait for a reply... */
8265       W (ret);
8266       return ret;
8267     }
8268
8269   /* Return the good/bad news */
8270   return (vam->retval);
8271 }
8272
8273 static int
8274 api_mpls_ip_bind_unbind (vat_main_t * vam)
8275 {
8276   unformat_input_t *i = vam->input;
8277   vl_api_mpls_ip_bind_unbind_t *mp;
8278   u32 ip_table_id = 0;
8279   u8 create_table_if_needed = 0;
8280   u8 is_bind = 1;
8281   u8 is_ip4 = 1;
8282   ip4_address_t v4_address;
8283   ip6_address_t v6_address;
8284   u32 address_length;
8285   u8 address_set = 0;
8286   mpls_label_t local_label = MPLS_LABEL_INVALID;
8287   int ret;
8288
8289   /* Parse args required to build the message */
8290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (i, "%U/%d", unformat_ip4_address,
8293                     &v4_address, &address_length))
8294         {
8295           is_ip4 = 1;
8296           address_set = 1;
8297         }
8298       else if (unformat (i, "%U/%d", unformat_ip6_address,
8299                          &v6_address, &address_length))
8300         {
8301           is_ip4 = 0;
8302           address_set = 1;
8303         }
8304       else if (unformat (i, "%d", &local_label))
8305         ;
8306       else if (unformat (i, "create-table"))
8307         create_table_if_needed = 1;
8308       else if (unformat (i, "table-id %d", &ip_table_id))
8309         ;
8310       else if (unformat (i, "unbind"))
8311         is_bind = 0;
8312       else if (unformat (i, "bind"))
8313         is_bind = 1;
8314       else
8315         {
8316           clib_warning ("parse error '%U'", format_unformat_error, i);
8317           return -99;
8318         }
8319     }
8320
8321   if (!address_set)
8322     {
8323       errmsg ("IP addres not set");
8324       return -99;
8325     }
8326
8327   if (MPLS_LABEL_INVALID == local_label)
8328     {
8329       errmsg ("missing label");
8330       return -99;
8331     }
8332
8333   /* Construct the API message */
8334   M (MPLS_IP_BIND_UNBIND, mp);
8335
8336   mp->mb_create_table_if_needed = create_table_if_needed;
8337   mp->mb_is_bind = is_bind;
8338   mp->mb_is_ip4 = is_ip4;
8339   mp->mb_ip_table_id = ntohl (ip_table_id);
8340   mp->mb_mpls_table_id = 0;
8341   mp->mb_label = ntohl (local_label);
8342   mp->mb_address_length = address_length;
8343
8344   if (is_ip4)
8345     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8346   else
8347     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8348
8349   /* send it... */
8350   S (mp);
8351
8352   /* Wait for a reply... */
8353   W (ret);
8354   return ret;
8355 }
8356
8357 static int
8358 api_proxy_arp_add_del (vat_main_t * vam)
8359 {
8360   unformat_input_t *i = vam->input;
8361   vl_api_proxy_arp_add_del_t *mp;
8362   u32 vrf_id = 0;
8363   u8 is_add = 1;
8364   ip4_address_t lo, hi;
8365   u8 range_set = 0;
8366   int ret;
8367
8368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8369     {
8370       if (unformat (i, "vrf %d", &vrf_id))
8371         ;
8372       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8373                          unformat_ip4_address, &hi))
8374         range_set = 1;
8375       else if (unformat (i, "del"))
8376         is_add = 0;
8377       else
8378         {
8379           clib_warning ("parse error '%U'", format_unformat_error, i);
8380           return -99;
8381         }
8382     }
8383
8384   if (range_set == 0)
8385     {
8386       errmsg ("address range not set");
8387       return -99;
8388     }
8389
8390   M (PROXY_ARP_ADD_DEL, mp);
8391
8392   mp->vrf_id = ntohl (vrf_id);
8393   mp->is_add = is_add;
8394   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8395   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8396
8397   S (mp);
8398   W (ret);
8399   return ret;
8400 }
8401
8402 static int
8403 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8404 {
8405   unformat_input_t *i = vam->input;
8406   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8407   u32 sw_if_index;
8408   u8 enable = 1;
8409   u8 sw_if_index_set = 0;
8410   int ret;
8411
8412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8413     {
8414       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8415         sw_if_index_set = 1;
8416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8417         sw_if_index_set = 1;
8418       else if (unformat (i, "enable"))
8419         enable = 1;
8420       else if (unformat (i, "disable"))
8421         enable = 0;
8422       else
8423         {
8424           clib_warning ("parse error '%U'", format_unformat_error, i);
8425           return -99;
8426         }
8427     }
8428
8429   if (sw_if_index_set == 0)
8430     {
8431       errmsg ("missing interface name or sw_if_index");
8432       return -99;
8433     }
8434
8435   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8436
8437   mp->sw_if_index = ntohl (sw_if_index);
8438   mp->enable_disable = enable;
8439
8440   S (mp);
8441   W (ret);
8442   return ret;
8443 }
8444
8445 static int
8446 api_mpls_tunnel_add_del (vat_main_t * vam)
8447 {
8448   unformat_input_t *i = vam->input;
8449   vl_api_mpls_tunnel_add_del_t *mp;
8450
8451   u8 is_add = 1;
8452   u8 l2_only = 0;
8453   u32 sw_if_index = ~0;
8454   u32 next_hop_sw_if_index = ~0;
8455   u32 next_hop_proto_is_ip4 = 1;
8456
8457   u32 next_hop_table_id = 0;
8458   ip4_address_t v4_next_hop_address = {
8459     .as_u32 = 0,
8460   };
8461   ip6_address_t v6_next_hop_address = { {0} };
8462   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8463   int ret;
8464
8465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8466     {
8467       if (unformat (i, "add"))
8468         is_add = 1;
8469       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8470         is_add = 0;
8471       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8472         ;
8473       else if (unformat (i, "via %U",
8474                          unformat_ip4_address, &v4_next_hop_address))
8475         {
8476           next_hop_proto_is_ip4 = 1;
8477         }
8478       else if (unformat (i, "via %U",
8479                          unformat_ip6_address, &v6_next_hop_address))
8480         {
8481           next_hop_proto_is_ip4 = 0;
8482         }
8483       else if (unformat (i, "l2-only"))
8484         l2_only = 1;
8485       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8486         ;
8487       else if (unformat (i, "out-label %d", &next_hop_out_label))
8488         vec_add1 (labels, ntohl (next_hop_out_label));
8489       else
8490         {
8491           clib_warning ("parse error '%U'", format_unformat_error, i);
8492           return -99;
8493         }
8494     }
8495
8496   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8497
8498   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8499   mp->mt_sw_if_index = ntohl (sw_if_index);
8500   mp->mt_is_add = is_add;
8501   mp->mt_l2_only = l2_only;
8502   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8503   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8504
8505   mp->mt_next_hop_n_out_labels = vec_len (labels);
8506
8507   if (0 != mp->mt_next_hop_n_out_labels)
8508     {
8509       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8510                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8511       vec_free (labels);
8512     }
8513
8514   if (next_hop_proto_is_ip4)
8515     {
8516       clib_memcpy (mp->mt_next_hop,
8517                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8518     }
8519   else
8520     {
8521       clib_memcpy (mp->mt_next_hop,
8522                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8523     }
8524
8525   S (mp);
8526   W (ret);
8527   return ret;
8528 }
8529
8530 static int
8531 api_sw_interface_set_unnumbered (vat_main_t * vam)
8532 {
8533   unformat_input_t *i = vam->input;
8534   vl_api_sw_interface_set_unnumbered_t *mp;
8535   u32 sw_if_index;
8536   u32 unnum_sw_index = ~0;
8537   u8 is_add = 1;
8538   u8 sw_if_index_set = 0;
8539   int ret;
8540
8541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8542     {
8543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8544         sw_if_index_set = 1;
8545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8546         sw_if_index_set = 1;
8547       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8548         ;
8549       else if (unformat (i, "del"))
8550         is_add = 0;
8551       else
8552         {
8553           clib_warning ("parse error '%U'", format_unformat_error, i);
8554           return -99;
8555         }
8556     }
8557
8558   if (sw_if_index_set == 0)
8559     {
8560       errmsg ("missing interface name or sw_if_index");
8561       return -99;
8562     }
8563
8564   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8565
8566   mp->sw_if_index = ntohl (sw_if_index);
8567   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8568   mp->is_add = is_add;
8569
8570   S (mp);
8571   W (ret);
8572   return ret;
8573 }
8574
8575 static int
8576 api_ip_neighbor_add_del (vat_main_t * vam)
8577 {
8578   unformat_input_t *i = vam->input;
8579   vl_api_ip_neighbor_add_del_t *mp;
8580   u32 sw_if_index;
8581   u8 sw_if_index_set = 0;
8582   u8 is_add = 1;
8583   u8 is_static = 0;
8584   u8 is_no_fib_entry = 0;
8585   u8 mac_address[6];
8586   u8 mac_set = 0;
8587   u8 v4_address_set = 0;
8588   u8 v6_address_set = 0;
8589   ip4_address_t v4address;
8590   ip6_address_t v6address;
8591   int ret;
8592
8593   memset (mac_address, 0, sizeof (mac_address));
8594
8595   /* Parse args required to build the message */
8596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8597     {
8598       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8599         {
8600           mac_set = 1;
8601         }
8602       else if (unformat (i, "del"))
8603         is_add = 0;
8604       else
8605         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8606         sw_if_index_set = 1;
8607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "is_static"))
8610         is_static = 1;
8611       else if (unformat (i, "no-fib-entry"))
8612         is_no_fib_entry = 1;
8613       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8614         v4_address_set = 1;
8615       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8616         v6_address_set = 1;
8617       else
8618         {
8619           clib_warning ("parse error '%U'", format_unformat_error, i);
8620           return -99;
8621         }
8622     }
8623
8624   if (sw_if_index_set == 0)
8625     {
8626       errmsg ("missing interface name or sw_if_index");
8627       return -99;
8628     }
8629   if (v4_address_set && v6_address_set)
8630     {
8631       errmsg ("both v4 and v6 addresses set");
8632       return -99;
8633     }
8634   if (!v4_address_set && !v6_address_set)
8635     {
8636       errmsg ("no address set");
8637       return -99;
8638     }
8639
8640   /* Construct the API message */
8641   M (IP_NEIGHBOR_ADD_DEL, mp);
8642
8643   mp->sw_if_index = ntohl (sw_if_index);
8644   mp->is_add = is_add;
8645   mp->is_static = is_static;
8646   mp->is_no_adj_fib = is_no_fib_entry;
8647   if (mac_set)
8648     clib_memcpy (mp->mac_address, mac_address, 6);
8649   if (v6_address_set)
8650     {
8651       mp->is_ipv6 = 1;
8652       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8653     }
8654   else
8655     {
8656       /* mp->is_ipv6 = 0; via memset in M macro above */
8657       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8658     }
8659
8660   /* send it... */
8661   S (mp);
8662
8663   /* Wait for a reply, return good/bad news  */
8664   W (ret);
8665   return ret;
8666 }
8667
8668 static int
8669 api_reset_vrf (vat_main_t * vam)
8670 {
8671   unformat_input_t *i = vam->input;
8672   vl_api_reset_vrf_t *mp;
8673   u32 vrf_id = 0;
8674   u8 is_ipv6 = 0;
8675   u8 vrf_id_set = 0;
8676   int ret;
8677
8678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8679     {
8680       if (unformat (i, "vrf %d", &vrf_id))
8681         vrf_id_set = 1;
8682       else if (unformat (i, "ipv6"))
8683         is_ipv6 = 1;
8684       else
8685         {
8686           clib_warning ("parse error '%U'", format_unformat_error, i);
8687           return -99;
8688         }
8689     }
8690
8691   if (vrf_id_set == 0)
8692     {
8693       errmsg ("missing vrf id");
8694       return -99;
8695     }
8696
8697   M (RESET_VRF, mp);
8698
8699   mp->vrf_id = ntohl (vrf_id);
8700   mp->is_ipv6 = is_ipv6;
8701
8702   S (mp);
8703   W (ret);
8704   return ret;
8705 }
8706
8707 static int
8708 api_create_vlan_subif (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_create_vlan_subif_t *mp;
8712   u32 sw_if_index;
8713   u8 sw_if_index_set = 0;
8714   u32 vlan_id;
8715   u8 vlan_id_set = 0;
8716   int ret;
8717
8718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8719     {
8720       if (unformat (i, "sw_if_index %d", &sw_if_index))
8721         sw_if_index_set = 1;
8722       else
8723         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8724         sw_if_index_set = 1;
8725       else if (unformat (i, "vlan %d", &vlan_id))
8726         vlan_id_set = 1;
8727       else
8728         {
8729           clib_warning ("parse error '%U'", format_unformat_error, i);
8730           return -99;
8731         }
8732     }
8733
8734   if (sw_if_index_set == 0)
8735     {
8736       errmsg ("missing interface name or sw_if_index");
8737       return -99;
8738     }
8739
8740   if (vlan_id_set == 0)
8741     {
8742       errmsg ("missing vlan_id");
8743       return -99;
8744     }
8745   M (CREATE_VLAN_SUBIF, mp);
8746
8747   mp->sw_if_index = ntohl (sw_if_index);
8748   mp->vlan_id = ntohl (vlan_id);
8749
8750   S (mp);
8751   W (ret);
8752   return ret;
8753 }
8754
8755 #define foreach_create_subif_bit                \
8756 _(no_tags)                                      \
8757 _(one_tag)                                      \
8758 _(two_tags)                                     \
8759 _(dot1ad)                                       \
8760 _(exact_match)                                  \
8761 _(default_sub)                                  \
8762 _(outer_vlan_id_any)                            \
8763 _(inner_vlan_id_any)
8764
8765 static int
8766 api_create_subif (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_create_subif_t *mp;
8770   u32 sw_if_index;
8771   u8 sw_if_index_set = 0;
8772   u32 sub_id;
8773   u8 sub_id_set = 0;
8774   u32 no_tags = 0;
8775   u32 one_tag = 0;
8776   u32 two_tags = 0;
8777   u32 dot1ad = 0;
8778   u32 exact_match = 0;
8779   u32 default_sub = 0;
8780   u32 outer_vlan_id_any = 0;
8781   u32 inner_vlan_id_any = 0;
8782   u32 tmp;
8783   u16 outer_vlan_id = 0;
8784   u16 inner_vlan_id = 0;
8785   int ret;
8786
8787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8788     {
8789       if (unformat (i, "sw_if_index %d", &sw_if_index))
8790         sw_if_index_set = 1;
8791       else
8792         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8793         sw_if_index_set = 1;
8794       else if (unformat (i, "sub_id %d", &sub_id))
8795         sub_id_set = 1;
8796       else if (unformat (i, "outer_vlan_id %d", &tmp))
8797         outer_vlan_id = tmp;
8798       else if (unformat (i, "inner_vlan_id %d", &tmp))
8799         inner_vlan_id = tmp;
8800
8801 #define _(a) else if (unformat (i, #a)) a = 1 ;
8802       foreach_create_subif_bit
8803 #undef _
8804         else
8805         {
8806           clib_warning ("parse error '%U'", format_unformat_error, i);
8807           return -99;
8808         }
8809     }
8810
8811   if (sw_if_index_set == 0)
8812     {
8813       errmsg ("missing interface name or sw_if_index");
8814       return -99;
8815     }
8816
8817   if (sub_id_set == 0)
8818     {
8819       errmsg ("missing sub_id");
8820       return -99;
8821     }
8822   M (CREATE_SUBIF, mp);
8823
8824   mp->sw_if_index = ntohl (sw_if_index);
8825   mp->sub_id = ntohl (sub_id);
8826
8827 #define _(a) mp->a = a;
8828   foreach_create_subif_bit;
8829 #undef _
8830
8831   mp->outer_vlan_id = ntohs (outer_vlan_id);
8832   mp->inner_vlan_id = ntohs (inner_vlan_id);
8833
8834   S (mp);
8835   W (ret);
8836   return ret;
8837 }
8838
8839 static int
8840 api_oam_add_del (vat_main_t * vam)
8841 {
8842   unformat_input_t *i = vam->input;
8843   vl_api_oam_add_del_t *mp;
8844   u32 vrf_id = 0;
8845   u8 is_add = 1;
8846   ip4_address_t src, dst;
8847   u8 src_set = 0;
8848   u8 dst_set = 0;
8849   int ret;
8850
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "vrf %d", &vrf_id))
8854         ;
8855       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8856         src_set = 1;
8857       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8858         dst_set = 1;
8859       else if (unformat (i, "del"))
8860         is_add = 0;
8861       else
8862         {
8863           clib_warning ("parse error '%U'", format_unformat_error, i);
8864           return -99;
8865         }
8866     }
8867
8868   if (src_set == 0)
8869     {
8870       errmsg ("missing src addr");
8871       return -99;
8872     }
8873
8874   if (dst_set == 0)
8875     {
8876       errmsg ("missing dst addr");
8877       return -99;
8878     }
8879
8880   M (OAM_ADD_DEL, mp);
8881
8882   mp->vrf_id = ntohl (vrf_id);
8883   mp->is_add = is_add;
8884   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8885   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8886
8887   S (mp);
8888   W (ret);
8889   return ret;
8890 }
8891
8892 static int
8893 api_reset_fib (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_reset_fib_t *mp;
8897   u32 vrf_id = 0;
8898   u8 is_ipv6 = 0;
8899   u8 vrf_id_set = 0;
8900
8901   int ret;
8902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8903     {
8904       if (unformat (i, "vrf %d", &vrf_id))
8905         vrf_id_set = 1;
8906       else if (unformat (i, "ipv6"))
8907         is_ipv6 = 1;
8908       else
8909         {
8910           clib_warning ("parse error '%U'", format_unformat_error, i);
8911           return -99;
8912         }
8913     }
8914
8915   if (vrf_id_set == 0)
8916     {
8917       errmsg ("missing vrf id");
8918       return -99;
8919     }
8920
8921   M (RESET_FIB, mp);
8922
8923   mp->vrf_id = ntohl (vrf_id);
8924   mp->is_ipv6 = is_ipv6;
8925
8926   S (mp);
8927   W (ret);
8928   return ret;
8929 }
8930
8931 static int
8932 api_dhcp_proxy_config (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_dhcp_proxy_config_t *mp;
8936   u32 rx_vrf_id = 0;
8937   u32 server_vrf_id = 0;
8938   u8 is_add = 1;
8939   u8 v4_address_set = 0;
8940   u8 v6_address_set = 0;
8941   ip4_address_t v4address;
8942   ip6_address_t v6address;
8943   u8 v4_src_address_set = 0;
8944   u8 v6_src_address_set = 0;
8945   ip4_address_t v4srcaddress;
8946   ip6_address_t v6srcaddress;
8947   int ret;
8948
8949   /* Parse args required to build the message */
8950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8951     {
8952       if (unformat (i, "del"))
8953         is_add = 0;
8954       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8955         ;
8956       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8957         ;
8958       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8959         v4_address_set = 1;
8960       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8961         v6_address_set = 1;
8962       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8963         v4_src_address_set = 1;
8964       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8965         v6_src_address_set = 1;
8966       else
8967         break;
8968     }
8969
8970   if (v4_address_set && v6_address_set)
8971     {
8972       errmsg ("both v4 and v6 server addresses set");
8973       return -99;
8974     }
8975   if (!v4_address_set && !v6_address_set)
8976     {
8977       errmsg ("no server addresses set");
8978       return -99;
8979     }
8980
8981   if (v4_src_address_set && v6_src_address_set)
8982     {
8983       errmsg ("both v4 and v6  src addresses set");
8984       return -99;
8985     }
8986   if (!v4_src_address_set && !v6_src_address_set)
8987     {
8988       errmsg ("no src addresses set");
8989       return -99;
8990     }
8991
8992   if (!(v4_src_address_set && v4_address_set) &&
8993       !(v6_src_address_set && v6_address_set))
8994     {
8995       errmsg ("no matching server and src addresses set");
8996       return -99;
8997     }
8998
8999   /* Construct the API message */
9000   M (DHCP_PROXY_CONFIG, mp);
9001
9002   mp->is_add = is_add;
9003   mp->rx_vrf_id = ntohl (rx_vrf_id);
9004   mp->server_vrf_id = ntohl (server_vrf_id);
9005   if (v6_address_set)
9006     {
9007       mp->is_ipv6 = 1;
9008       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9009       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9010     }
9011   else
9012     {
9013       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9014       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9015     }
9016
9017   /* send it... */
9018   S (mp);
9019
9020   /* Wait for a reply, return good/bad news  */
9021   W (ret);
9022   return ret;
9023 }
9024
9025 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9026 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9027
9028 static void
9029 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9030 {
9031   vat_main_t *vam = &vat_main;
9032   u32 i, count = mp->count;
9033   vl_api_dhcp_server_t *s;
9034
9035   if (mp->is_ipv6)
9036     print (vam->ofp,
9037            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9038            ntohl (mp->rx_vrf_id),
9039            format_ip6_address, mp->dhcp_src_address,
9040            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9041   else
9042     print (vam->ofp,
9043            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9044            ntohl (mp->rx_vrf_id),
9045            format_ip4_address, mp->dhcp_src_address,
9046            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9047
9048   for (i = 0; i < count; i++)
9049     {
9050       s = &mp->servers[i];
9051
9052       if (mp->is_ipv6)
9053         print (vam->ofp,
9054                " Server Table-ID %d, Server Address %U",
9055                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9056       else
9057         print (vam->ofp,
9058                " Server Table-ID %d, Server Address %U",
9059                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9060     }
9061 }
9062
9063 static void vl_api_dhcp_proxy_details_t_handler_json
9064   (vl_api_dhcp_proxy_details_t * mp)
9065 {
9066   vat_main_t *vam = &vat_main;
9067   vat_json_node_t *node = NULL;
9068   u32 i, count = mp->count;
9069   struct in_addr ip4;
9070   struct in6_addr ip6;
9071   vl_api_dhcp_server_t *s;
9072
9073   if (VAT_JSON_ARRAY != vam->json_tree.type)
9074     {
9075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9076       vat_json_init_array (&vam->json_tree);
9077     }
9078   node = vat_json_array_add (&vam->json_tree);
9079
9080   vat_json_init_object (node);
9081   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9082   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9083   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9084
9085   if (mp->is_ipv6)
9086     {
9087       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9088       vat_json_object_add_ip6 (node, "src_address", ip6);
9089     }
9090   else
9091     {
9092       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9093       vat_json_object_add_ip4 (node, "src_address", ip4);
9094     }
9095
9096   for (i = 0; i < count; i++)
9097     {
9098       s = &mp->servers[i];
9099
9100       vat_json_object_add_uint (node, "server-table-id",
9101                                 ntohl (s->server_vrf_id));
9102
9103       if (mp->is_ipv6)
9104         {
9105           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9106           vat_json_object_add_ip4 (node, "src_address", ip4);
9107         }
9108       else
9109         {
9110           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9111           vat_json_object_add_ip6 (node, "server_address", ip6);
9112         }
9113     }
9114 }
9115
9116 static int
9117 api_dhcp_proxy_dump (vat_main_t * vam)
9118 {
9119   unformat_input_t *i = vam->input;
9120   vl_api_control_ping_t *mp_ping;
9121   vl_api_dhcp_proxy_dump_t *mp;
9122   u8 is_ipv6 = 0;
9123   int ret;
9124
9125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9126     {
9127       if (unformat (i, "ipv6"))
9128         is_ipv6 = 1;
9129       else
9130         {
9131           clib_warning ("parse error '%U'", format_unformat_error, i);
9132           return -99;
9133         }
9134     }
9135
9136   M (DHCP_PROXY_DUMP, mp);
9137
9138   mp->is_ip6 = is_ipv6;
9139   S (mp);
9140
9141   /* Use a control ping for synchronization */
9142   MPING (CONTROL_PING, mp_ping);
9143   S (mp_ping);
9144
9145   W (ret);
9146   return ret;
9147 }
9148
9149 static int
9150 api_dhcp_proxy_set_vss (vat_main_t * vam)
9151 {
9152   unformat_input_t *i = vam->input;
9153   vl_api_dhcp_proxy_set_vss_t *mp;
9154   u8 is_ipv6 = 0;
9155   u8 is_add = 1;
9156   u32 tbl_id;
9157   u8 tbl_id_set = 0;
9158   u32 oui;
9159   u8 oui_set = 0;
9160   u32 fib_id;
9161   u8 fib_id_set = 0;
9162   int ret;
9163
9164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9165     {
9166       if (unformat (i, "tbl_id %d", &tbl_id))
9167         tbl_id_set = 1;
9168       if (unformat (i, "fib_id %d", &fib_id))
9169         fib_id_set = 1;
9170       if (unformat (i, "oui %d", &oui))
9171         oui_set = 1;
9172       else if (unformat (i, "ipv6"))
9173         is_ipv6 = 1;
9174       else if (unformat (i, "del"))
9175         is_add = 0;
9176       else
9177         {
9178           clib_warning ("parse error '%U'", format_unformat_error, i);
9179           return -99;
9180         }
9181     }
9182
9183   if (tbl_id_set == 0)
9184     {
9185       errmsg ("missing tbl id");
9186       return -99;
9187     }
9188
9189   if (fib_id_set == 0)
9190     {
9191       errmsg ("missing fib id");
9192       return -99;
9193     }
9194   if (oui_set == 0)
9195     {
9196       errmsg ("missing oui");
9197       return -99;
9198     }
9199
9200   M (DHCP_PROXY_SET_VSS, mp);
9201   mp->tbl_id = ntohl (tbl_id);
9202   mp->fib_id = ntohl (fib_id);
9203   mp->oui = ntohl (oui);
9204   mp->is_ipv6 = is_ipv6;
9205   mp->is_add = is_add;
9206
9207   S (mp);
9208   W (ret);
9209   return ret;
9210 }
9211
9212 static int
9213 api_dhcp_client_config (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_dhcp_client_config_t *mp;
9217   u32 sw_if_index;
9218   u8 sw_if_index_set = 0;
9219   u8 is_add = 1;
9220   u8 *hostname = 0;
9221   u8 disable_event = 0;
9222   int ret;
9223
9224   /* Parse args required to build the message */
9225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9226     {
9227       if (unformat (i, "del"))
9228         is_add = 0;
9229       else
9230         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9231         sw_if_index_set = 1;
9232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9233         sw_if_index_set = 1;
9234       else if (unformat (i, "hostname %s", &hostname))
9235         ;
9236       else if (unformat (i, "disable_event"))
9237         disable_event = 1;
9238       else
9239         break;
9240     }
9241
9242   if (sw_if_index_set == 0)
9243     {
9244       errmsg ("missing interface name or sw_if_index");
9245       return -99;
9246     }
9247
9248   if (vec_len (hostname) > 63)
9249     {
9250       errmsg ("hostname too long");
9251     }
9252   vec_add1 (hostname, 0);
9253
9254   /* Construct the API message */
9255   M (DHCP_CLIENT_CONFIG, mp);
9256
9257   mp->sw_if_index = htonl (sw_if_index);
9258   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9259   vec_free (hostname);
9260   mp->is_add = is_add;
9261   mp->want_dhcp_event = disable_event ? 0 : 1;
9262   mp->pid = htonl (getpid ());
9263
9264   /* send it... */
9265   S (mp);
9266
9267   /* Wait for a reply, return good/bad news  */
9268   W (ret);
9269   return ret;
9270 }
9271
9272 static int
9273 api_set_ip_flow_hash (vat_main_t * vam)
9274 {
9275   unformat_input_t *i = vam->input;
9276   vl_api_set_ip_flow_hash_t *mp;
9277   u32 vrf_id = 0;
9278   u8 is_ipv6 = 0;
9279   u8 vrf_id_set = 0;
9280   u8 src = 0;
9281   u8 dst = 0;
9282   u8 sport = 0;
9283   u8 dport = 0;
9284   u8 proto = 0;
9285   u8 reverse = 0;
9286   int ret;
9287
9288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289     {
9290       if (unformat (i, "vrf %d", &vrf_id))
9291         vrf_id_set = 1;
9292       else if (unformat (i, "ipv6"))
9293         is_ipv6 = 1;
9294       else if (unformat (i, "src"))
9295         src = 1;
9296       else if (unformat (i, "dst"))
9297         dst = 1;
9298       else if (unformat (i, "sport"))
9299         sport = 1;
9300       else if (unformat (i, "dport"))
9301         dport = 1;
9302       else if (unformat (i, "proto"))
9303         proto = 1;
9304       else if (unformat (i, "reverse"))
9305         reverse = 1;
9306
9307       else
9308         {
9309           clib_warning ("parse error '%U'", format_unformat_error, i);
9310           return -99;
9311         }
9312     }
9313
9314   if (vrf_id_set == 0)
9315     {
9316       errmsg ("missing vrf id");
9317       return -99;
9318     }
9319
9320   M (SET_IP_FLOW_HASH, mp);
9321   mp->src = src;
9322   mp->dst = dst;
9323   mp->sport = sport;
9324   mp->dport = dport;
9325   mp->proto = proto;
9326   mp->reverse = reverse;
9327   mp->vrf_id = ntohl (vrf_id);
9328   mp->is_ipv6 = is_ipv6;
9329
9330   S (mp);
9331   W (ret);
9332   return ret;
9333 }
9334
9335 static int
9336 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9337 {
9338   unformat_input_t *i = vam->input;
9339   vl_api_sw_interface_ip6_enable_disable_t *mp;
9340   u32 sw_if_index;
9341   u8 sw_if_index_set = 0;
9342   u8 enable = 0;
9343   int ret;
9344
9345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9346     {
9347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9348         sw_if_index_set = 1;
9349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9350         sw_if_index_set = 1;
9351       else if (unformat (i, "enable"))
9352         enable = 1;
9353       else if (unformat (i, "disable"))
9354         enable = 0;
9355       else
9356         {
9357           clib_warning ("parse error '%U'", format_unformat_error, i);
9358           return -99;
9359         }
9360     }
9361
9362   if (sw_if_index_set == 0)
9363     {
9364       errmsg ("missing interface name or sw_if_index");
9365       return -99;
9366     }
9367
9368   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9369
9370   mp->sw_if_index = ntohl (sw_if_index);
9371   mp->enable = enable;
9372
9373   S (mp);
9374   W (ret);
9375   return ret;
9376 }
9377
9378 static int
9379 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9380 {
9381   unformat_input_t *i = vam->input;
9382   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9383   u32 sw_if_index;
9384   u8 sw_if_index_set = 0;
9385   u8 v6_address_set = 0;
9386   ip6_address_t v6address;
9387   int ret;
9388
9389   /* Parse args required to build the message */
9390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9391     {
9392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9393         sw_if_index_set = 1;
9394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9395         sw_if_index_set = 1;
9396       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9397         v6_address_set = 1;
9398       else
9399         break;
9400     }
9401
9402   if (sw_if_index_set == 0)
9403     {
9404       errmsg ("missing interface name or sw_if_index");
9405       return -99;
9406     }
9407   if (!v6_address_set)
9408     {
9409       errmsg ("no address set");
9410       return -99;
9411     }
9412
9413   /* Construct the API message */
9414   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9415
9416   mp->sw_if_index = ntohl (sw_if_index);
9417   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9418
9419   /* send it... */
9420   S (mp);
9421
9422   /* Wait for a reply, return good/bad news  */
9423   W (ret);
9424   return ret;
9425 }
9426
9427 static int
9428 api_ip6nd_proxy_add_del (vat_main_t * vam)
9429 {
9430   unformat_input_t *i = vam->input;
9431   vl_api_ip6nd_proxy_add_del_t *mp;
9432   u32 sw_if_index = ~0;
9433   u8 v6_address_set = 0;
9434   ip6_address_t v6address;
9435   u8 is_del = 0;
9436   int ret;
9437
9438   /* Parse args required to build the message */
9439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9442         ;
9443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9444         ;
9445       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9446         v6_address_set = 1;
9447       if (unformat (i, "del"))
9448         is_del = 1;
9449       else
9450         {
9451           clib_warning ("parse error '%U'", format_unformat_error, i);
9452           return -99;
9453         }
9454     }
9455
9456   if (sw_if_index == ~0)
9457     {
9458       errmsg ("missing interface name or sw_if_index");
9459       return -99;
9460     }
9461   if (!v6_address_set)
9462     {
9463       errmsg ("no address set");
9464       return -99;
9465     }
9466
9467   /* Construct the API message */
9468   M (IP6ND_PROXY_ADD_DEL, mp);
9469
9470   mp->is_del = is_del;
9471   mp->sw_if_index = ntohl (sw_if_index);
9472   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9473
9474   /* send it... */
9475   S (mp);
9476
9477   /* Wait for a reply, return good/bad news  */
9478   W (ret);
9479   return ret;
9480 }
9481
9482 static int
9483 api_ip6nd_proxy_dump (vat_main_t * vam)
9484 {
9485   vl_api_ip6nd_proxy_dump_t *mp;
9486   vl_api_control_ping_t *mp_ping;
9487   int ret;
9488
9489   M (IP6ND_PROXY_DUMP, mp);
9490
9491   S (mp);
9492
9493   /* Use a control ping for synchronization */
9494   MPING (CONTROL_PING, mp_ping);
9495   S (mp_ping);
9496
9497   W (ret);
9498   return ret;
9499 }
9500
9501 static void vl_api_ip6nd_proxy_details_t_handler
9502   (vl_api_ip6nd_proxy_details_t * mp)
9503 {
9504   vat_main_t *vam = &vat_main;
9505
9506   print (vam->ofp, "host %U sw_if_index %d",
9507          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9508 }
9509
9510 static void vl_api_ip6nd_proxy_details_t_handler_json
9511   (vl_api_ip6nd_proxy_details_t * mp)
9512 {
9513   vat_main_t *vam = &vat_main;
9514   struct in6_addr ip6;
9515   vat_json_node_t *node = NULL;
9516
9517   if (VAT_JSON_ARRAY != vam->json_tree.type)
9518     {
9519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9520       vat_json_init_array (&vam->json_tree);
9521     }
9522   node = vat_json_array_add (&vam->json_tree);
9523
9524   vat_json_init_object (node);
9525   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9526
9527   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9528   vat_json_object_add_ip6 (node, "host", ip6);
9529 }
9530
9531 static int
9532 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9533 {
9534   unformat_input_t *i = vam->input;
9535   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9536   u32 sw_if_index;
9537   u8 sw_if_index_set = 0;
9538   u32 address_length = 0;
9539   u8 v6_address_set = 0;
9540   ip6_address_t v6address;
9541   u8 use_default = 0;
9542   u8 no_advertise = 0;
9543   u8 off_link = 0;
9544   u8 no_autoconfig = 0;
9545   u8 no_onlink = 0;
9546   u8 is_no = 0;
9547   u32 val_lifetime = 0;
9548   u32 pref_lifetime = 0;
9549   int ret;
9550
9551   /* Parse args required to build the message */
9552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9553     {
9554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "%U/%d",
9559                          unformat_ip6_address, &v6address, &address_length))
9560         v6_address_set = 1;
9561       else if (unformat (i, "val_life %d", &val_lifetime))
9562         ;
9563       else if (unformat (i, "pref_life %d", &pref_lifetime))
9564         ;
9565       else if (unformat (i, "def"))
9566         use_default = 1;
9567       else if (unformat (i, "noadv"))
9568         no_advertise = 1;
9569       else if (unformat (i, "offl"))
9570         off_link = 1;
9571       else if (unformat (i, "noauto"))
9572         no_autoconfig = 1;
9573       else if (unformat (i, "nolink"))
9574         no_onlink = 1;
9575       else if (unformat (i, "isno"))
9576         is_no = 1;
9577       else
9578         {
9579           clib_warning ("parse error '%U'", format_unformat_error, i);
9580           return -99;
9581         }
9582     }
9583
9584   if (sw_if_index_set == 0)
9585     {
9586       errmsg ("missing interface name or sw_if_index");
9587       return -99;
9588     }
9589   if (!v6_address_set)
9590     {
9591       errmsg ("no address set");
9592       return -99;
9593     }
9594
9595   /* Construct the API message */
9596   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9597
9598   mp->sw_if_index = ntohl (sw_if_index);
9599   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9600   mp->address_length = address_length;
9601   mp->use_default = use_default;
9602   mp->no_advertise = no_advertise;
9603   mp->off_link = off_link;
9604   mp->no_autoconfig = no_autoconfig;
9605   mp->no_onlink = no_onlink;
9606   mp->is_no = is_no;
9607   mp->val_lifetime = ntohl (val_lifetime);
9608   mp->pref_lifetime = ntohl (pref_lifetime);
9609
9610   /* send it... */
9611   S (mp);
9612
9613   /* Wait for a reply, return good/bad news  */
9614   W (ret);
9615   return ret;
9616 }
9617
9618 static int
9619 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9620 {
9621   unformat_input_t *i = vam->input;
9622   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9623   u32 sw_if_index;
9624   u8 sw_if_index_set = 0;
9625   u8 suppress = 0;
9626   u8 managed = 0;
9627   u8 other = 0;
9628   u8 ll_option = 0;
9629   u8 send_unicast = 0;
9630   u8 cease = 0;
9631   u8 is_no = 0;
9632   u8 default_router = 0;
9633   u32 max_interval = 0;
9634   u32 min_interval = 0;
9635   u32 lifetime = 0;
9636   u32 initial_count = 0;
9637   u32 initial_interval = 0;
9638   int ret;
9639
9640
9641   /* Parse args required to build the message */
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9645         sw_if_index_set = 1;
9646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9647         sw_if_index_set = 1;
9648       else if (unformat (i, "maxint %d", &max_interval))
9649         ;
9650       else if (unformat (i, "minint %d", &min_interval))
9651         ;
9652       else if (unformat (i, "life %d", &lifetime))
9653         ;
9654       else if (unformat (i, "count %d", &initial_count))
9655         ;
9656       else if (unformat (i, "interval %d", &initial_interval))
9657         ;
9658       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9659         suppress = 1;
9660       else if (unformat (i, "managed"))
9661         managed = 1;
9662       else if (unformat (i, "other"))
9663         other = 1;
9664       else if (unformat (i, "ll"))
9665         ll_option = 1;
9666       else if (unformat (i, "send"))
9667         send_unicast = 1;
9668       else if (unformat (i, "cease"))
9669         cease = 1;
9670       else if (unformat (i, "isno"))
9671         is_no = 1;
9672       else if (unformat (i, "def"))
9673         default_router = 1;
9674       else
9675         {
9676           clib_warning ("parse error '%U'", format_unformat_error, i);
9677           return -99;
9678         }
9679     }
9680
9681   if (sw_if_index_set == 0)
9682     {
9683       errmsg ("missing interface name or sw_if_index");
9684       return -99;
9685     }
9686
9687   /* Construct the API message */
9688   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9689
9690   mp->sw_if_index = ntohl (sw_if_index);
9691   mp->max_interval = ntohl (max_interval);
9692   mp->min_interval = ntohl (min_interval);
9693   mp->lifetime = ntohl (lifetime);
9694   mp->initial_count = ntohl (initial_count);
9695   mp->initial_interval = ntohl (initial_interval);
9696   mp->suppress = suppress;
9697   mp->managed = managed;
9698   mp->other = other;
9699   mp->ll_option = ll_option;
9700   mp->send_unicast = send_unicast;
9701   mp->cease = cease;
9702   mp->is_no = is_no;
9703   mp->default_router = default_router;
9704
9705   /* send it... */
9706   S (mp);
9707
9708   /* Wait for a reply, return good/bad news  */
9709   W (ret);
9710   return ret;
9711 }
9712
9713 static int
9714 api_set_arp_neighbor_limit (vat_main_t * vam)
9715 {
9716   unformat_input_t *i = vam->input;
9717   vl_api_set_arp_neighbor_limit_t *mp;
9718   u32 arp_nbr_limit;
9719   u8 limit_set = 0;
9720   u8 is_ipv6 = 0;
9721   int ret;
9722
9723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9724     {
9725       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9726         limit_set = 1;
9727       else if (unformat (i, "ipv6"))
9728         is_ipv6 = 1;
9729       else
9730         {
9731           clib_warning ("parse error '%U'", format_unformat_error, i);
9732           return -99;
9733         }
9734     }
9735
9736   if (limit_set == 0)
9737     {
9738       errmsg ("missing limit value");
9739       return -99;
9740     }
9741
9742   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9743
9744   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9745   mp->is_ipv6 = is_ipv6;
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 static int
9753 api_l2_patch_add_del (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_l2_patch_add_del_t *mp;
9757   u32 rx_sw_if_index;
9758   u8 rx_sw_if_index_set = 0;
9759   u32 tx_sw_if_index;
9760   u8 tx_sw_if_index_set = 0;
9761   u8 is_add = 1;
9762   int ret;
9763
9764   /* Parse args required to build the message */
9765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9766     {
9767       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9768         rx_sw_if_index_set = 1;
9769       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9770         tx_sw_if_index_set = 1;
9771       else if (unformat (i, "rx"))
9772         {
9773           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9774             {
9775               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9776                             &rx_sw_if_index))
9777                 rx_sw_if_index_set = 1;
9778             }
9779           else
9780             break;
9781         }
9782       else if (unformat (i, "tx"))
9783         {
9784           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9785             {
9786               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9787                             &tx_sw_if_index))
9788                 tx_sw_if_index_set = 1;
9789             }
9790           else
9791             break;
9792         }
9793       else if (unformat (i, "del"))
9794         is_add = 0;
9795       else
9796         break;
9797     }
9798
9799   if (rx_sw_if_index_set == 0)
9800     {
9801       errmsg ("missing rx interface name or rx_sw_if_index");
9802       return -99;
9803     }
9804
9805   if (tx_sw_if_index_set == 0)
9806     {
9807       errmsg ("missing tx interface name or tx_sw_if_index");
9808       return -99;
9809     }
9810
9811   M (L2_PATCH_ADD_DEL, mp);
9812
9813   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9814   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9815   mp->is_add = is_add;
9816
9817   S (mp);
9818   W (ret);
9819   return ret;
9820 }
9821
9822 u8 is_del;
9823 u8 localsid_addr[16];
9824 u8 end_psp;
9825 u8 behavior;
9826 u32 sw_if_index;
9827 u32 vlan_index;
9828 u32 fib_table;
9829 u8 nh_addr[16];
9830
9831 static int
9832 api_sr_localsid_add_del (vat_main_t * vam)
9833 {
9834   unformat_input_t *i = vam->input;
9835   vl_api_sr_localsid_add_del_t *mp;
9836
9837   u8 is_del;
9838   ip6_address_t localsid;
9839   u8 end_psp = 0;
9840   u8 behavior = ~0;
9841   u32 sw_if_index;
9842   u32 fib_table = ~(u32) 0;
9843   ip6_address_t next_hop;
9844
9845   bool nexthop_set = 0;
9846
9847   int ret;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "del"))
9852         is_del = 1;
9853       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9854       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9855         nexthop_set = 1;
9856       else if (unformat (i, "behavior %u", &behavior));
9857       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9858       else if (unformat (i, "fib-table %u", &fib_table));
9859       else if (unformat (i, "end.psp %u", &behavior));
9860       else
9861         break;
9862     }
9863
9864   M (SR_LOCALSID_ADD_DEL, mp);
9865
9866   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9867   if (nexthop_set)
9868     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9869   mp->behavior = behavior;
9870   mp->sw_if_index = ntohl (sw_if_index);
9871   mp->fib_table = ntohl (fib_table);
9872   mp->end_psp = end_psp;
9873   mp->is_del = is_del;
9874
9875   S (mp);
9876   W (ret);
9877   return ret;
9878 }
9879
9880 static int
9881 api_ioam_enable (vat_main_t * vam)
9882 {
9883   unformat_input_t *input = vam->input;
9884   vl_api_ioam_enable_t *mp;
9885   u32 id = 0;
9886   int has_trace_option = 0;
9887   int has_pot_option = 0;
9888   int has_seqno_option = 0;
9889   int has_analyse_option = 0;
9890   int ret;
9891
9892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9893     {
9894       if (unformat (input, "trace"))
9895         has_trace_option = 1;
9896       else if (unformat (input, "pot"))
9897         has_pot_option = 1;
9898       else if (unformat (input, "seqno"))
9899         has_seqno_option = 1;
9900       else if (unformat (input, "analyse"))
9901         has_analyse_option = 1;
9902       else
9903         break;
9904     }
9905   M (IOAM_ENABLE, mp);
9906   mp->id = htons (id);
9907   mp->seqno = has_seqno_option;
9908   mp->analyse = has_analyse_option;
9909   mp->pot_enable = has_pot_option;
9910   mp->trace_enable = has_trace_option;
9911
9912   S (mp);
9913   W (ret);
9914   return ret;
9915 }
9916
9917
9918 static int
9919 api_ioam_disable (vat_main_t * vam)
9920 {
9921   vl_api_ioam_disable_t *mp;
9922   int ret;
9923
9924   M (IOAM_DISABLE, mp);
9925   S (mp);
9926   W (ret);
9927   return ret;
9928 }
9929
9930 #define foreach_tcp_proto_field                 \
9931 _(src_port)                                     \
9932 _(dst_port)
9933
9934 #define foreach_udp_proto_field                 \
9935 _(src_port)                                     \
9936 _(dst_port)
9937
9938 #define foreach_ip4_proto_field                 \
9939 _(src_address)                                  \
9940 _(dst_address)                                  \
9941 _(tos)                                          \
9942 _(length)                                       \
9943 _(fragment_id)                                  \
9944 _(ttl)                                          \
9945 _(protocol)                                     \
9946 _(checksum)
9947
9948 typedef struct
9949 {
9950   u16 src_port, dst_port;
9951 } tcpudp_header_t;
9952
9953 #if VPP_API_TEST_BUILTIN == 0
9954 uword
9955 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9956 {
9957   u8 **maskp = va_arg (*args, u8 **);
9958   u8 *mask = 0;
9959   u8 found_something = 0;
9960   tcp_header_t *tcp;
9961
9962 #define _(a) u8 a=0;
9963   foreach_tcp_proto_field;
9964 #undef _
9965
9966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9967     {
9968       if (0);
9969 #define _(a) else if (unformat (input, #a)) a=1;
9970       foreach_tcp_proto_field
9971 #undef _
9972         else
9973         break;
9974     }
9975
9976 #define _(a) found_something += a;
9977   foreach_tcp_proto_field;
9978 #undef _
9979
9980   if (found_something == 0)
9981     return 0;
9982
9983   vec_validate (mask, sizeof (*tcp) - 1);
9984
9985   tcp = (tcp_header_t *) mask;
9986
9987 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9988   foreach_tcp_proto_field;
9989 #undef _
9990
9991   *maskp = mask;
9992   return 1;
9993 }
9994
9995 uword
9996 unformat_udp_mask (unformat_input_t * input, va_list * args)
9997 {
9998   u8 **maskp = va_arg (*args, u8 **);
9999   u8 *mask = 0;
10000   u8 found_something = 0;
10001   udp_header_t *udp;
10002
10003 #define _(a) u8 a=0;
10004   foreach_udp_proto_field;
10005 #undef _
10006
10007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (0);
10010 #define _(a) else if (unformat (input, #a)) a=1;
10011       foreach_udp_proto_field
10012 #undef _
10013         else
10014         break;
10015     }
10016
10017 #define _(a) found_something += a;
10018   foreach_udp_proto_field;
10019 #undef _
10020
10021   if (found_something == 0)
10022     return 0;
10023
10024   vec_validate (mask, sizeof (*udp) - 1);
10025
10026   udp = (udp_header_t *) mask;
10027
10028 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10029   foreach_udp_proto_field;
10030 #undef _
10031
10032   *maskp = mask;
10033   return 1;
10034 }
10035
10036 uword
10037 unformat_l4_mask (unformat_input_t * input, va_list * args)
10038 {
10039   u8 **maskp = va_arg (*args, u8 **);
10040   u16 src_port = 0, dst_port = 0;
10041   tcpudp_header_t *tcpudp;
10042
10043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10044     {
10045       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10046         return 1;
10047       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10048         return 1;
10049       else if (unformat (input, "src_port"))
10050         src_port = 0xFFFF;
10051       else if (unformat (input, "dst_port"))
10052         dst_port = 0xFFFF;
10053       else
10054         return 0;
10055     }
10056
10057   if (!src_port && !dst_port)
10058     return 0;
10059
10060   u8 *mask = 0;
10061   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10062
10063   tcpudp = (tcpudp_header_t *) mask;
10064   tcpudp->src_port = src_port;
10065   tcpudp->dst_port = dst_port;
10066
10067   *maskp = mask;
10068
10069   return 1;
10070 }
10071
10072 uword
10073 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10074 {
10075   u8 **maskp = va_arg (*args, u8 **);
10076   u8 *mask = 0;
10077   u8 found_something = 0;
10078   ip4_header_t *ip;
10079
10080 #define _(a) u8 a=0;
10081   foreach_ip4_proto_field;
10082 #undef _
10083   u8 version = 0;
10084   u8 hdr_length = 0;
10085
10086
10087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10088     {
10089       if (unformat (input, "version"))
10090         version = 1;
10091       else if (unformat (input, "hdr_length"))
10092         hdr_length = 1;
10093       else if (unformat (input, "src"))
10094         src_address = 1;
10095       else if (unformat (input, "dst"))
10096         dst_address = 1;
10097       else if (unformat (input, "proto"))
10098         protocol = 1;
10099
10100 #define _(a) else if (unformat (input, #a)) a=1;
10101       foreach_ip4_proto_field
10102 #undef _
10103         else
10104         break;
10105     }
10106
10107 #define _(a) found_something += a;
10108   foreach_ip4_proto_field;
10109 #undef _
10110
10111   if (found_something == 0)
10112     return 0;
10113
10114   vec_validate (mask, sizeof (*ip) - 1);
10115
10116   ip = (ip4_header_t *) mask;
10117
10118 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10119   foreach_ip4_proto_field;
10120 #undef _
10121
10122   ip->ip_version_and_header_length = 0;
10123
10124   if (version)
10125     ip->ip_version_and_header_length |= 0xF0;
10126
10127   if (hdr_length)
10128     ip->ip_version_and_header_length |= 0x0F;
10129
10130   *maskp = mask;
10131   return 1;
10132 }
10133
10134 #define foreach_ip6_proto_field                 \
10135 _(src_address)                                  \
10136 _(dst_address)                                  \
10137 _(payload_length)                               \
10138 _(hop_limit)                                    \
10139 _(protocol)
10140
10141 uword
10142 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10143 {
10144   u8 **maskp = va_arg (*args, u8 **);
10145   u8 *mask = 0;
10146   u8 found_something = 0;
10147   ip6_header_t *ip;
10148   u32 ip_version_traffic_class_and_flow_label;
10149
10150 #define _(a) u8 a=0;
10151   foreach_ip6_proto_field;
10152 #undef _
10153   u8 version = 0;
10154   u8 traffic_class = 0;
10155   u8 flow_label = 0;
10156
10157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10158     {
10159       if (unformat (input, "version"))
10160         version = 1;
10161       else if (unformat (input, "traffic-class"))
10162         traffic_class = 1;
10163       else if (unformat (input, "flow-label"))
10164         flow_label = 1;
10165       else if (unformat (input, "src"))
10166         src_address = 1;
10167       else if (unformat (input, "dst"))
10168         dst_address = 1;
10169       else if (unformat (input, "proto"))
10170         protocol = 1;
10171
10172 #define _(a) else if (unformat (input, #a)) a=1;
10173       foreach_ip6_proto_field
10174 #undef _
10175         else
10176         break;
10177     }
10178
10179 #define _(a) found_something += a;
10180   foreach_ip6_proto_field;
10181 #undef _
10182
10183   if (found_something == 0)
10184     return 0;
10185
10186   vec_validate (mask, sizeof (*ip) - 1);
10187
10188   ip = (ip6_header_t *) mask;
10189
10190 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10191   foreach_ip6_proto_field;
10192 #undef _
10193
10194   ip_version_traffic_class_and_flow_label = 0;
10195
10196   if (version)
10197     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10198
10199   if (traffic_class)
10200     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10201
10202   if (flow_label)
10203     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10204
10205   ip->ip_version_traffic_class_and_flow_label =
10206     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10207
10208   *maskp = mask;
10209   return 1;
10210 }
10211
10212 uword
10213 unformat_l3_mask (unformat_input_t * input, va_list * args)
10214 {
10215   u8 **maskp = va_arg (*args, u8 **);
10216
10217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10220         return 1;
10221       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10222         return 1;
10223       else
10224         break;
10225     }
10226   return 0;
10227 }
10228
10229 uword
10230 unformat_l2_mask (unformat_input_t * input, va_list * args)
10231 {
10232   u8 **maskp = va_arg (*args, u8 **);
10233   u8 *mask = 0;
10234   u8 src = 0;
10235   u8 dst = 0;
10236   u8 proto = 0;
10237   u8 tag1 = 0;
10238   u8 tag2 = 0;
10239   u8 ignore_tag1 = 0;
10240   u8 ignore_tag2 = 0;
10241   u8 cos1 = 0;
10242   u8 cos2 = 0;
10243   u8 dot1q = 0;
10244   u8 dot1ad = 0;
10245   int len = 14;
10246
10247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10248     {
10249       if (unformat (input, "src"))
10250         src = 1;
10251       else if (unformat (input, "dst"))
10252         dst = 1;
10253       else if (unformat (input, "proto"))
10254         proto = 1;
10255       else if (unformat (input, "tag1"))
10256         tag1 = 1;
10257       else if (unformat (input, "tag2"))
10258         tag2 = 1;
10259       else if (unformat (input, "ignore-tag1"))
10260         ignore_tag1 = 1;
10261       else if (unformat (input, "ignore-tag2"))
10262         ignore_tag2 = 1;
10263       else if (unformat (input, "cos1"))
10264         cos1 = 1;
10265       else if (unformat (input, "cos2"))
10266         cos2 = 1;
10267       else if (unformat (input, "dot1q"))
10268         dot1q = 1;
10269       else if (unformat (input, "dot1ad"))
10270         dot1ad = 1;
10271       else
10272         break;
10273     }
10274   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10275        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10276     return 0;
10277
10278   if (tag1 || ignore_tag1 || cos1 || dot1q)
10279     len = 18;
10280   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10281     len = 22;
10282
10283   vec_validate (mask, len - 1);
10284
10285   if (dst)
10286     memset (mask, 0xff, 6);
10287
10288   if (src)
10289     memset (mask + 6, 0xff, 6);
10290
10291   if (tag2 || dot1ad)
10292     {
10293       /* inner vlan tag */
10294       if (tag2)
10295         {
10296           mask[19] = 0xff;
10297           mask[18] = 0x0f;
10298         }
10299       if (cos2)
10300         mask[18] |= 0xe0;
10301       if (proto)
10302         mask[21] = mask[20] = 0xff;
10303       if (tag1)
10304         {
10305           mask[15] = 0xff;
10306           mask[14] = 0x0f;
10307         }
10308       if (cos1)
10309         mask[14] |= 0xe0;
10310       *maskp = mask;
10311       return 1;
10312     }
10313   if (tag1 | dot1q)
10314     {
10315       if (tag1)
10316         {
10317           mask[15] = 0xff;
10318           mask[14] = 0x0f;
10319         }
10320       if (cos1)
10321         mask[14] |= 0xe0;
10322       if (proto)
10323         mask[16] = mask[17] = 0xff;
10324
10325       *maskp = mask;
10326       return 1;
10327     }
10328   if (cos2)
10329     mask[18] |= 0xe0;
10330   if (cos1)
10331     mask[14] |= 0xe0;
10332   if (proto)
10333     mask[12] = mask[13] = 0xff;
10334
10335   *maskp = mask;
10336   return 1;
10337 }
10338
10339 uword
10340 unformat_classify_mask (unformat_input_t * input, va_list * args)
10341 {
10342   u8 **maskp = va_arg (*args, u8 **);
10343   u32 *skipp = va_arg (*args, u32 *);
10344   u32 *matchp = va_arg (*args, u32 *);
10345   u32 match;
10346   u8 *mask = 0;
10347   u8 *l2 = 0;
10348   u8 *l3 = 0;
10349   u8 *l4 = 0;
10350   int i;
10351
10352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10353     {
10354       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10355         ;
10356       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10357         ;
10358       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10359         ;
10360       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10361         ;
10362       else
10363         break;
10364     }
10365
10366   if (l4 && !l3)
10367     {
10368       vec_free (mask);
10369       vec_free (l2);
10370       vec_free (l4);
10371       return 0;
10372     }
10373
10374   if (mask || l2 || l3 || l4)
10375     {
10376       if (l2 || l3 || l4)
10377         {
10378           /* "With a free Ethernet header in every package" */
10379           if (l2 == 0)
10380             vec_validate (l2, 13);
10381           mask = l2;
10382           if (vec_len (l3))
10383             {
10384               vec_append (mask, l3);
10385               vec_free (l3);
10386             }
10387           if (vec_len (l4))
10388             {
10389               vec_append (mask, l4);
10390               vec_free (l4);
10391             }
10392         }
10393
10394       /* Scan forward looking for the first significant mask octet */
10395       for (i = 0; i < vec_len (mask); i++)
10396         if (mask[i])
10397           break;
10398
10399       /* compute (skip, match) params */
10400       *skipp = i / sizeof (u32x4);
10401       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10402
10403       /* Pad mask to an even multiple of the vector size */
10404       while (vec_len (mask) % sizeof (u32x4))
10405         vec_add1 (mask, 0);
10406
10407       match = vec_len (mask) / sizeof (u32x4);
10408
10409       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10410         {
10411           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10412           if (*tmp || *(tmp + 1))
10413             break;
10414           match--;
10415         }
10416       if (match == 0)
10417         clib_warning ("BUG: match 0");
10418
10419       _vec_len (mask) = match * sizeof (u32x4);
10420
10421       *matchp = match;
10422       *maskp = mask;
10423
10424       return 1;
10425     }
10426
10427   return 0;
10428 }
10429 #endif /* VPP_API_TEST_BUILTIN */
10430
10431 #define foreach_l2_next                         \
10432 _(drop, DROP)                                   \
10433 _(ethernet, ETHERNET_INPUT)                     \
10434 _(ip4, IP4_INPUT)                               \
10435 _(ip6, IP6_INPUT)
10436
10437 uword
10438 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10439 {
10440   u32 *miss_next_indexp = va_arg (*args, u32 *);
10441   u32 next_index = 0;
10442   u32 tmp;
10443
10444 #define _(n,N) \
10445   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10446   foreach_l2_next;
10447 #undef _
10448
10449   if (unformat (input, "%d", &tmp))
10450     {
10451       next_index = tmp;
10452       goto out;
10453     }
10454
10455   return 0;
10456
10457 out:
10458   *miss_next_indexp = next_index;
10459   return 1;
10460 }
10461
10462 #define foreach_ip_next                         \
10463 _(drop, DROP)                                   \
10464 _(local, LOCAL)                                 \
10465 _(rewrite, REWRITE)
10466
10467 uword
10468 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10469 {
10470   u32 *miss_next_indexp = va_arg (*args, u32 *);
10471   u32 next_index = 0;
10472   u32 tmp;
10473
10474 #define _(n,N) \
10475   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10476   foreach_ip_next;
10477 #undef _
10478
10479   if (unformat (input, "%d", &tmp))
10480     {
10481       next_index = tmp;
10482       goto out;
10483     }
10484
10485   return 0;
10486
10487 out:
10488   *miss_next_indexp = next_index;
10489   return 1;
10490 }
10491
10492 #define foreach_acl_next                        \
10493 _(deny, DENY)
10494
10495 uword
10496 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10497 {
10498   u32 *miss_next_indexp = va_arg (*args, u32 *);
10499   u32 next_index = 0;
10500   u32 tmp;
10501
10502 #define _(n,N) \
10503   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10504   foreach_acl_next;
10505 #undef _
10506
10507   if (unformat (input, "permit"))
10508     {
10509       next_index = ~0;
10510       goto out;
10511     }
10512   else if (unformat (input, "%d", &tmp))
10513     {
10514       next_index = tmp;
10515       goto out;
10516     }
10517
10518   return 0;
10519
10520 out:
10521   *miss_next_indexp = next_index;
10522   return 1;
10523 }
10524
10525 uword
10526 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10527 {
10528   u32 *r = va_arg (*args, u32 *);
10529
10530   if (unformat (input, "conform-color"))
10531     *r = POLICE_CONFORM;
10532   else if (unformat (input, "exceed-color"))
10533     *r = POLICE_EXCEED;
10534   else
10535     return 0;
10536
10537   return 1;
10538 }
10539
10540 static int
10541 api_classify_add_del_table (vat_main_t * vam)
10542 {
10543   unformat_input_t *i = vam->input;
10544   vl_api_classify_add_del_table_t *mp;
10545
10546   u32 nbuckets = 2;
10547   u32 skip = ~0;
10548   u32 match = ~0;
10549   int is_add = 1;
10550   int del_chain = 0;
10551   u32 table_index = ~0;
10552   u32 next_table_index = ~0;
10553   u32 miss_next_index = ~0;
10554   u32 memory_size = 32 << 20;
10555   u8 *mask = 0;
10556   u32 current_data_flag = 0;
10557   int current_data_offset = 0;
10558   int ret;
10559
10560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (i, "del"))
10563         is_add = 0;
10564       else if (unformat (i, "del-chain"))
10565         {
10566           is_add = 0;
10567           del_chain = 1;
10568         }
10569       else if (unformat (i, "buckets %d", &nbuckets))
10570         ;
10571       else if (unformat (i, "memory_size %d", &memory_size))
10572         ;
10573       else if (unformat (i, "skip %d", &skip))
10574         ;
10575       else if (unformat (i, "match %d", &match))
10576         ;
10577       else if (unformat (i, "table %d", &table_index))
10578         ;
10579       else if (unformat (i, "mask %U", unformat_classify_mask,
10580                          &mask, &skip, &match))
10581         ;
10582       else if (unformat (i, "next-table %d", &next_table_index))
10583         ;
10584       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10585                          &miss_next_index))
10586         ;
10587       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10588                          &miss_next_index))
10589         ;
10590       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10591                          &miss_next_index))
10592         ;
10593       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10594         ;
10595       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10596         ;
10597       else
10598         break;
10599     }
10600
10601   if (is_add && mask == 0)
10602     {
10603       errmsg ("Mask required");
10604       return -99;
10605     }
10606
10607   if (is_add && skip == ~0)
10608     {
10609       errmsg ("skip count required");
10610       return -99;
10611     }
10612
10613   if (is_add && match == ~0)
10614     {
10615       errmsg ("match count required");
10616       return -99;
10617     }
10618
10619   if (!is_add && table_index == ~0)
10620     {
10621       errmsg ("table index required for delete");
10622       return -99;
10623     }
10624
10625   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10626
10627   mp->is_add = is_add;
10628   mp->del_chain = del_chain;
10629   mp->table_index = ntohl (table_index);
10630   mp->nbuckets = ntohl (nbuckets);
10631   mp->memory_size = ntohl (memory_size);
10632   mp->skip_n_vectors = ntohl (skip);
10633   mp->match_n_vectors = ntohl (match);
10634   mp->next_table_index = ntohl (next_table_index);
10635   mp->miss_next_index = ntohl (miss_next_index);
10636   mp->current_data_flag = ntohl (current_data_flag);
10637   mp->current_data_offset = ntohl (current_data_offset);
10638   clib_memcpy (mp->mask, mask, vec_len (mask));
10639
10640   vec_free (mask);
10641
10642   S (mp);
10643   W (ret);
10644   return ret;
10645 }
10646
10647 #if VPP_API_TEST_BUILTIN == 0
10648 uword
10649 unformat_l4_match (unformat_input_t * input, va_list * args)
10650 {
10651   u8 **matchp = va_arg (*args, u8 **);
10652
10653   u8 *proto_header = 0;
10654   int src_port = 0;
10655   int dst_port = 0;
10656
10657   tcpudp_header_t h;
10658
10659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10660     {
10661       if (unformat (input, "src_port %d", &src_port))
10662         ;
10663       else if (unformat (input, "dst_port %d", &dst_port))
10664         ;
10665       else
10666         return 0;
10667     }
10668
10669   h.src_port = clib_host_to_net_u16 (src_port);
10670   h.dst_port = clib_host_to_net_u16 (dst_port);
10671   vec_validate (proto_header, sizeof (h) - 1);
10672   memcpy (proto_header, &h, sizeof (h));
10673
10674   *matchp = proto_header;
10675
10676   return 1;
10677 }
10678
10679 uword
10680 unformat_ip4_match (unformat_input_t * input, va_list * args)
10681 {
10682   u8 **matchp = va_arg (*args, u8 **);
10683   u8 *match = 0;
10684   ip4_header_t *ip;
10685   int version = 0;
10686   u32 version_val;
10687   int hdr_length = 0;
10688   u32 hdr_length_val;
10689   int src = 0, dst = 0;
10690   ip4_address_t src_val, dst_val;
10691   int proto = 0;
10692   u32 proto_val;
10693   int tos = 0;
10694   u32 tos_val;
10695   int length = 0;
10696   u32 length_val;
10697   int fragment_id = 0;
10698   u32 fragment_id_val;
10699   int ttl = 0;
10700   int ttl_val;
10701   int checksum = 0;
10702   u32 checksum_val;
10703
10704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (input, "version %d", &version_val))
10707         version = 1;
10708       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10709         hdr_length = 1;
10710       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10711         src = 1;
10712       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10713         dst = 1;
10714       else if (unformat (input, "proto %d", &proto_val))
10715         proto = 1;
10716       else if (unformat (input, "tos %d", &tos_val))
10717         tos = 1;
10718       else if (unformat (input, "length %d", &length_val))
10719         length = 1;
10720       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10721         fragment_id = 1;
10722       else if (unformat (input, "ttl %d", &ttl_val))
10723         ttl = 1;
10724       else if (unformat (input, "checksum %d", &checksum_val))
10725         checksum = 1;
10726       else
10727         break;
10728     }
10729
10730   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10731       + ttl + checksum == 0)
10732     return 0;
10733
10734   /*
10735    * Aligned because we use the real comparison functions
10736    */
10737   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10738
10739   ip = (ip4_header_t *) match;
10740
10741   /* These are realistically matched in practice */
10742   if (src)
10743     ip->src_address.as_u32 = src_val.as_u32;
10744
10745   if (dst)
10746     ip->dst_address.as_u32 = dst_val.as_u32;
10747
10748   if (proto)
10749     ip->protocol = proto_val;
10750
10751
10752   /* These are not, but they're included for completeness */
10753   if (version)
10754     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10755
10756   if (hdr_length)
10757     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10758
10759   if (tos)
10760     ip->tos = tos_val;
10761
10762   if (length)
10763     ip->length = clib_host_to_net_u16 (length_val);
10764
10765   if (ttl)
10766     ip->ttl = ttl_val;
10767
10768   if (checksum)
10769     ip->checksum = clib_host_to_net_u16 (checksum_val);
10770
10771   *matchp = match;
10772   return 1;
10773 }
10774
10775 uword
10776 unformat_ip6_match (unformat_input_t * input, va_list * args)
10777 {
10778   u8 **matchp = va_arg (*args, u8 **);
10779   u8 *match = 0;
10780   ip6_header_t *ip;
10781   int version = 0;
10782   u32 version_val;
10783   u8 traffic_class = 0;
10784   u32 traffic_class_val = 0;
10785   u8 flow_label = 0;
10786   u8 flow_label_val;
10787   int src = 0, dst = 0;
10788   ip6_address_t src_val, dst_val;
10789   int proto = 0;
10790   u32 proto_val;
10791   int payload_length = 0;
10792   u32 payload_length_val;
10793   int hop_limit = 0;
10794   int hop_limit_val;
10795   u32 ip_version_traffic_class_and_flow_label;
10796
10797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10798     {
10799       if (unformat (input, "version %d", &version_val))
10800         version = 1;
10801       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10802         traffic_class = 1;
10803       else if (unformat (input, "flow_label %d", &flow_label_val))
10804         flow_label = 1;
10805       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10806         src = 1;
10807       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10808         dst = 1;
10809       else if (unformat (input, "proto %d", &proto_val))
10810         proto = 1;
10811       else if (unformat (input, "payload_length %d", &payload_length_val))
10812         payload_length = 1;
10813       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10814         hop_limit = 1;
10815       else
10816         break;
10817     }
10818
10819   if (version + traffic_class + flow_label + src + dst + proto +
10820       payload_length + hop_limit == 0)
10821     return 0;
10822
10823   /*
10824    * Aligned because we use the real comparison functions
10825    */
10826   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10827
10828   ip = (ip6_header_t *) match;
10829
10830   if (src)
10831     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10832
10833   if (dst)
10834     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10835
10836   if (proto)
10837     ip->protocol = proto_val;
10838
10839   ip_version_traffic_class_and_flow_label = 0;
10840
10841   if (version)
10842     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10843
10844   if (traffic_class)
10845     ip_version_traffic_class_and_flow_label |=
10846       (traffic_class_val & 0xFF) << 20;
10847
10848   if (flow_label)
10849     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10850
10851   ip->ip_version_traffic_class_and_flow_label =
10852     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10853
10854   if (payload_length)
10855     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10856
10857   if (hop_limit)
10858     ip->hop_limit = hop_limit_val;
10859
10860   *matchp = match;
10861   return 1;
10862 }
10863
10864 uword
10865 unformat_l3_match (unformat_input_t * input, va_list * args)
10866 {
10867   u8 **matchp = va_arg (*args, u8 **);
10868
10869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10870     {
10871       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10872         return 1;
10873       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10874         return 1;
10875       else
10876         break;
10877     }
10878   return 0;
10879 }
10880
10881 uword
10882 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10883 {
10884   u8 *tagp = va_arg (*args, u8 *);
10885   u32 tag;
10886
10887   if (unformat (input, "%d", &tag))
10888     {
10889       tagp[0] = (tag >> 8) & 0x0F;
10890       tagp[1] = tag & 0xFF;
10891       return 1;
10892     }
10893
10894   return 0;
10895 }
10896
10897 uword
10898 unformat_l2_match (unformat_input_t * input, va_list * args)
10899 {
10900   u8 **matchp = va_arg (*args, u8 **);
10901   u8 *match = 0;
10902   u8 src = 0;
10903   u8 src_val[6];
10904   u8 dst = 0;
10905   u8 dst_val[6];
10906   u8 proto = 0;
10907   u16 proto_val;
10908   u8 tag1 = 0;
10909   u8 tag1_val[2];
10910   u8 tag2 = 0;
10911   u8 tag2_val[2];
10912   int len = 14;
10913   u8 ignore_tag1 = 0;
10914   u8 ignore_tag2 = 0;
10915   u8 cos1 = 0;
10916   u8 cos2 = 0;
10917   u32 cos1_val = 0;
10918   u32 cos2_val = 0;
10919
10920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10923         src = 1;
10924       else
10925         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10926         dst = 1;
10927       else if (unformat (input, "proto %U",
10928                          unformat_ethernet_type_host_byte_order, &proto_val))
10929         proto = 1;
10930       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10931         tag1 = 1;
10932       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10933         tag2 = 1;
10934       else if (unformat (input, "ignore-tag1"))
10935         ignore_tag1 = 1;
10936       else if (unformat (input, "ignore-tag2"))
10937         ignore_tag2 = 1;
10938       else if (unformat (input, "cos1 %d", &cos1_val))
10939         cos1 = 1;
10940       else if (unformat (input, "cos2 %d", &cos2_val))
10941         cos2 = 1;
10942       else
10943         break;
10944     }
10945   if ((src + dst + proto + tag1 + tag2 +
10946        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10947     return 0;
10948
10949   if (tag1 || ignore_tag1 || cos1)
10950     len = 18;
10951   if (tag2 || ignore_tag2 || cos2)
10952     len = 22;
10953
10954   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10955
10956   if (dst)
10957     clib_memcpy (match, dst_val, 6);
10958
10959   if (src)
10960     clib_memcpy (match + 6, src_val, 6);
10961
10962   if (tag2)
10963     {
10964       /* inner vlan tag */
10965       match[19] = tag2_val[1];
10966       match[18] = tag2_val[0];
10967       if (cos2)
10968         match[18] |= (cos2_val & 0x7) << 5;
10969       if (proto)
10970         {
10971           match[21] = proto_val & 0xff;
10972           match[20] = proto_val >> 8;
10973         }
10974       if (tag1)
10975         {
10976           match[15] = tag1_val[1];
10977           match[14] = tag1_val[0];
10978         }
10979       if (cos1)
10980         match[14] |= (cos1_val & 0x7) << 5;
10981       *matchp = match;
10982       return 1;
10983     }
10984   if (tag1)
10985     {
10986       match[15] = tag1_val[1];
10987       match[14] = tag1_val[0];
10988       if (proto)
10989         {
10990           match[17] = proto_val & 0xff;
10991           match[16] = proto_val >> 8;
10992         }
10993       if (cos1)
10994         match[14] |= (cos1_val & 0x7) << 5;
10995
10996       *matchp = match;
10997       return 1;
10998     }
10999   if (cos2)
11000     match[18] |= (cos2_val & 0x7) << 5;
11001   if (cos1)
11002     match[14] |= (cos1_val & 0x7) << 5;
11003   if (proto)
11004     {
11005       match[13] = proto_val & 0xff;
11006       match[12] = proto_val >> 8;
11007     }
11008
11009   *matchp = match;
11010   return 1;
11011 }
11012 #endif
11013
11014 uword
11015 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11016 {
11017   u8 **matchp = va_arg (*args, u8 **);
11018   u32 skip_n_vectors = va_arg (*args, u32);
11019   u32 match_n_vectors = va_arg (*args, u32);
11020
11021   u8 *match = 0;
11022   u8 *l2 = 0;
11023   u8 *l3 = 0;
11024   u8 *l4 = 0;
11025
11026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11027     {
11028       if (unformat (input, "hex %U", unformat_hex_string, &match))
11029         ;
11030       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11031         ;
11032       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11033         ;
11034       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11035         ;
11036       else
11037         break;
11038     }
11039
11040   if (l4 && !l3)
11041     {
11042       vec_free (match);
11043       vec_free (l2);
11044       vec_free (l4);
11045       return 0;
11046     }
11047
11048   if (match || l2 || l3 || l4)
11049     {
11050       if (l2 || l3 || l4)
11051         {
11052           /* "Win a free Ethernet header in every packet" */
11053           if (l2 == 0)
11054             vec_validate_aligned (l2, 13, sizeof (u32x4));
11055           match = l2;
11056           if (vec_len (l3))
11057             {
11058               vec_append_aligned (match, l3, sizeof (u32x4));
11059               vec_free (l3);
11060             }
11061           if (vec_len (l4))
11062             {
11063               vec_append_aligned (match, l4, sizeof (u32x4));
11064               vec_free (l4);
11065             }
11066         }
11067
11068       /* Make sure the vector is big enough even if key is all 0's */
11069       vec_validate_aligned
11070         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11071          sizeof (u32x4));
11072
11073       /* Set size, include skipped vectors */
11074       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11075
11076       *matchp = match;
11077
11078       return 1;
11079     }
11080
11081   return 0;
11082 }
11083
11084 static int
11085 api_classify_add_del_session (vat_main_t * vam)
11086 {
11087   unformat_input_t *i = vam->input;
11088   vl_api_classify_add_del_session_t *mp;
11089   int is_add = 1;
11090   u32 table_index = ~0;
11091   u32 hit_next_index = ~0;
11092   u32 opaque_index = ~0;
11093   u8 *match = 0;
11094   i32 advance = 0;
11095   u32 skip_n_vectors = 0;
11096   u32 match_n_vectors = 0;
11097   u32 action = 0;
11098   u32 metadata = 0;
11099   int ret;
11100
11101   /*
11102    * Warning: you have to supply skip_n and match_n
11103    * because the API client cant simply look at the classify
11104    * table object.
11105    */
11106
11107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11108     {
11109       if (unformat (i, "del"))
11110         is_add = 0;
11111       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11112                          &hit_next_index))
11113         ;
11114       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11115                          &hit_next_index))
11116         ;
11117       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11118                          &hit_next_index))
11119         ;
11120       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11121         ;
11122       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11123         ;
11124       else if (unformat (i, "opaque-index %d", &opaque_index))
11125         ;
11126       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11127         ;
11128       else if (unformat (i, "match_n %d", &match_n_vectors))
11129         ;
11130       else if (unformat (i, "match %U", api_unformat_classify_match,
11131                          &match, skip_n_vectors, match_n_vectors))
11132         ;
11133       else if (unformat (i, "advance %d", &advance))
11134         ;
11135       else if (unformat (i, "table-index %d", &table_index))
11136         ;
11137       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11138         action = 1;
11139       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11140         action = 2;
11141       else if (unformat (i, "action %d", &action))
11142         ;
11143       else if (unformat (i, "metadata %d", &metadata))
11144         ;
11145       else
11146         break;
11147     }
11148
11149   if (table_index == ~0)
11150     {
11151       errmsg ("Table index required");
11152       return -99;
11153     }
11154
11155   if (is_add && match == 0)
11156     {
11157       errmsg ("Match value required");
11158       return -99;
11159     }
11160
11161   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11162
11163   mp->is_add = is_add;
11164   mp->table_index = ntohl (table_index);
11165   mp->hit_next_index = ntohl (hit_next_index);
11166   mp->opaque_index = ntohl (opaque_index);
11167   mp->advance = ntohl (advance);
11168   mp->action = action;
11169   mp->metadata = ntohl (metadata);
11170   clib_memcpy (mp->match, match, vec_len (match));
11171   vec_free (match);
11172
11173   S (mp);
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static int
11179 api_classify_set_interface_ip_table (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_classify_set_interface_ip_table_t *mp;
11183   u32 sw_if_index;
11184   int sw_if_index_set;
11185   u32 table_index = ~0;
11186   u8 is_ipv6 = 0;
11187   int ret;
11188
11189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11190     {
11191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "table %d", &table_index))
11196         ;
11197       else
11198         {
11199           clib_warning ("parse error '%U'", format_unformat_error, i);
11200           return -99;
11201         }
11202     }
11203
11204   if (sw_if_index_set == 0)
11205     {
11206       errmsg ("missing interface name or sw_if_index");
11207       return -99;
11208     }
11209
11210
11211   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11212
11213   mp->sw_if_index = ntohl (sw_if_index);
11214   mp->table_index = ntohl (table_index);
11215   mp->is_ipv6 = is_ipv6;
11216
11217   S (mp);
11218   W (ret);
11219   return ret;
11220 }
11221
11222 static int
11223 api_classify_set_interface_l2_tables (vat_main_t * vam)
11224 {
11225   unformat_input_t *i = vam->input;
11226   vl_api_classify_set_interface_l2_tables_t *mp;
11227   u32 sw_if_index;
11228   int sw_if_index_set;
11229   u32 ip4_table_index = ~0;
11230   u32 ip6_table_index = ~0;
11231   u32 other_table_index = ~0;
11232   u32 is_input = 1;
11233   int ret;
11234
11235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11236     {
11237       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11238         sw_if_index_set = 1;
11239       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11240         sw_if_index_set = 1;
11241       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11242         ;
11243       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11244         ;
11245       else if (unformat (i, "other-table %d", &other_table_index))
11246         ;
11247       else if (unformat (i, "is-input %d", &is_input))
11248         ;
11249       else
11250         {
11251           clib_warning ("parse error '%U'", format_unformat_error, i);
11252           return -99;
11253         }
11254     }
11255
11256   if (sw_if_index_set == 0)
11257     {
11258       errmsg ("missing interface name or sw_if_index");
11259       return -99;
11260     }
11261
11262
11263   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11264
11265   mp->sw_if_index = ntohl (sw_if_index);
11266   mp->ip4_table_index = ntohl (ip4_table_index);
11267   mp->ip6_table_index = ntohl (ip6_table_index);
11268   mp->other_table_index = ntohl (other_table_index);
11269   mp->is_input = (u8) is_input;
11270
11271   S (mp);
11272   W (ret);
11273   return ret;
11274 }
11275
11276 static int
11277 api_set_ipfix_exporter (vat_main_t * vam)
11278 {
11279   unformat_input_t *i = vam->input;
11280   vl_api_set_ipfix_exporter_t *mp;
11281   ip4_address_t collector_address;
11282   u8 collector_address_set = 0;
11283   u32 collector_port = ~0;
11284   ip4_address_t src_address;
11285   u8 src_address_set = 0;
11286   u32 vrf_id = ~0;
11287   u32 path_mtu = ~0;
11288   u32 template_interval = ~0;
11289   u8 udp_checksum = 0;
11290   int ret;
11291
11292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11293     {
11294       if (unformat (i, "collector_address %U", unformat_ip4_address,
11295                     &collector_address))
11296         collector_address_set = 1;
11297       else if (unformat (i, "collector_port %d", &collector_port))
11298         ;
11299       else if (unformat (i, "src_address %U", unformat_ip4_address,
11300                          &src_address))
11301         src_address_set = 1;
11302       else if (unformat (i, "vrf_id %d", &vrf_id))
11303         ;
11304       else if (unformat (i, "path_mtu %d", &path_mtu))
11305         ;
11306       else if (unformat (i, "template_interval %d", &template_interval))
11307         ;
11308       else if (unformat (i, "udp_checksum"))
11309         udp_checksum = 1;
11310       else
11311         break;
11312     }
11313
11314   if (collector_address_set == 0)
11315     {
11316       errmsg ("collector_address required");
11317       return -99;
11318     }
11319
11320   if (src_address_set == 0)
11321     {
11322       errmsg ("src_address required");
11323       return -99;
11324     }
11325
11326   M (SET_IPFIX_EXPORTER, mp);
11327
11328   memcpy (mp->collector_address, collector_address.data,
11329           sizeof (collector_address.data));
11330   mp->collector_port = htons ((u16) collector_port);
11331   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11332   mp->vrf_id = htonl (vrf_id);
11333   mp->path_mtu = htonl (path_mtu);
11334   mp->template_interval = htonl (template_interval);
11335   mp->udp_checksum = udp_checksum;
11336
11337   S (mp);
11338   W (ret);
11339   return ret;
11340 }
11341
11342 static int
11343 api_set_ipfix_classify_stream (vat_main_t * vam)
11344 {
11345   unformat_input_t *i = vam->input;
11346   vl_api_set_ipfix_classify_stream_t *mp;
11347   u32 domain_id = 0;
11348   u32 src_port = UDP_DST_PORT_ipfix;
11349   int ret;
11350
11351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (i, "domain %d", &domain_id))
11354         ;
11355       else if (unformat (i, "src_port %d", &src_port))
11356         ;
11357       else
11358         {
11359           errmsg ("unknown input `%U'", format_unformat_error, i);
11360           return -99;
11361         }
11362     }
11363
11364   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11365
11366   mp->domain_id = htonl (domain_id);
11367   mp->src_port = htons ((u16) src_port);
11368
11369   S (mp);
11370   W (ret);
11371   return ret;
11372 }
11373
11374 static int
11375 api_ipfix_classify_table_add_del (vat_main_t * vam)
11376 {
11377   unformat_input_t *i = vam->input;
11378   vl_api_ipfix_classify_table_add_del_t *mp;
11379   int is_add = -1;
11380   u32 classify_table_index = ~0;
11381   u8 ip_version = 0;
11382   u8 transport_protocol = 255;
11383   int ret;
11384
11385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11386     {
11387       if (unformat (i, "add"))
11388         is_add = 1;
11389       else if (unformat (i, "del"))
11390         is_add = 0;
11391       else if (unformat (i, "table %d", &classify_table_index))
11392         ;
11393       else if (unformat (i, "ip4"))
11394         ip_version = 4;
11395       else if (unformat (i, "ip6"))
11396         ip_version = 6;
11397       else if (unformat (i, "tcp"))
11398         transport_protocol = 6;
11399       else if (unformat (i, "udp"))
11400         transport_protocol = 17;
11401       else
11402         {
11403           errmsg ("unknown input `%U'", format_unformat_error, i);
11404           return -99;
11405         }
11406     }
11407
11408   if (is_add == -1)
11409     {
11410       errmsg ("expecting: add|del");
11411       return -99;
11412     }
11413   if (classify_table_index == ~0)
11414     {
11415       errmsg ("classifier table not specified");
11416       return -99;
11417     }
11418   if (ip_version == 0)
11419     {
11420       errmsg ("IP version not specified");
11421       return -99;
11422     }
11423
11424   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11425
11426   mp->is_add = is_add;
11427   mp->table_id = htonl (classify_table_index);
11428   mp->ip_version = ip_version;
11429   mp->transport_protocol = transport_protocol;
11430
11431   S (mp);
11432   W (ret);
11433   return ret;
11434 }
11435
11436 static int
11437 api_get_node_index (vat_main_t * vam)
11438 {
11439   unformat_input_t *i = vam->input;
11440   vl_api_get_node_index_t *mp;
11441   u8 *name = 0;
11442   int ret;
11443
11444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (i, "node %s", &name))
11447         ;
11448       else
11449         break;
11450     }
11451   if (name == 0)
11452     {
11453       errmsg ("node name required");
11454       return -99;
11455     }
11456   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11457     {
11458       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11459       return -99;
11460     }
11461
11462   M (GET_NODE_INDEX, mp);
11463   clib_memcpy (mp->node_name, name, vec_len (name));
11464   vec_free (name);
11465
11466   S (mp);
11467   W (ret);
11468   return ret;
11469 }
11470
11471 static int
11472 api_get_next_index (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_get_next_index_t *mp;
11476   u8 *node_name = 0, *next_node_name = 0;
11477   int ret;
11478
11479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11480     {
11481       if (unformat (i, "node-name %s", &node_name))
11482         ;
11483       else if (unformat (i, "next-node-name %s", &next_node_name))
11484         break;
11485     }
11486
11487   if (node_name == 0)
11488     {
11489       errmsg ("node name required");
11490       return -99;
11491     }
11492   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11493     {
11494       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11495       return -99;
11496     }
11497
11498   if (next_node_name == 0)
11499     {
11500       errmsg ("next node name required");
11501       return -99;
11502     }
11503   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11504     {
11505       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11506       return -99;
11507     }
11508
11509   M (GET_NEXT_INDEX, mp);
11510   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11511   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11512   vec_free (node_name);
11513   vec_free (next_node_name);
11514
11515   S (mp);
11516   W (ret);
11517   return ret;
11518 }
11519
11520 static int
11521 api_add_node_next (vat_main_t * vam)
11522 {
11523   unformat_input_t *i = vam->input;
11524   vl_api_add_node_next_t *mp;
11525   u8 *name = 0;
11526   u8 *next = 0;
11527   int ret;
11528
11529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (i, "node %s", &name))
11532         ;
11533       else if (unformat (i, "next %s", &next))
11534         ;
11535       else
11536         break;
11537     }
11538   if (name == 0)
11539     {
11540       errmsg ("node name required");
11541       return -99;
11542     }
11543   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11544     {
11545       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11546       return -99;
11547     }
11548   if (next == 0)
11549     {
11550       errmsg ("next node required");
11551       return -99;
11552     }
11553   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11554     {
11555       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11556       return -99;
11557     }
11558
11559   M (ADD_NODE_NEXT, mp);
11560   clib_memcpy (mp->node_name, name, vec_len (name));
11561   clib_memcpy (mp->next_name, next, vec_len (next));
11562   vec_free (name);
11563   vec_free (next);
11564
11565   S (mp);
11566   W (ret);
11567   return ret;
11568 }
11569
11570 static int
11571 api_l2tpv3_create_tunnel (vat_main_t * vam)
11572 {
11573   unformat_input_t *i = vam->input;
11574   ip6_address_t client_address, our_address;
11575   int client_address_set = 0;
11576   int our_address_set = 0;
11577   u32 local_session_id = 0;
11578   u32 remote_session_id = 0;
11579   u64 local_cookie = 0;
11580   u64 remote_cookie = 0;
11581   u8 l2_sublayer_present = 0;
11582   vl_api_l2tpv3_create_tunnel_t *mp;
11583   int ret;
11584
11585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (i, "client_address %U", unformat_ip6_address,
11588                     &client_address))
11589         client_address_set = 1;
11590       else if (unformat (i, "our_address %U", unformat_ip6_address,
11591                          &our_address))
11592         our_address_set = 1;
11593       else if (unformat (i, "local_session_id %d", &local_session_id))
11594         ;
11595       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11596         ;
11597       else if (unformat (i, "local_cookie %lld", &local_cookie))
11598         ;
11599       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11600         ;
11601       else if (unformat (i, "l2-sublayer-present"))
11602         l2_sublayer_present = 1;
11603       else
11604         break;
11605     }
11606
11607   if (client_address_set == 0)
11608     {
11609       errmsg ("client_address required");
11610       return -99;
11611     }
11612
11613   if (our_address_set == 0)
11614     {
11615       errmsg ("our_address required");
11616       return -99;
11617     }
11618
11619   M (L2TPV3_CREATE_TUNNEL, mp);
11620
11621   clib_memcpy (mp->client_address, client_address.as_u8,
11622                sizeof (mp->client_address));
11623
11624   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11625
11626   mp->local_session_id = ntohl (local_session_id);
11627   mp->remote_session_id = ntohl (remote_session_id);
11628   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11629   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11630   mp->l2_sublayer_present = l2_sublayer_present;
11631   mp->is_ipv6 = 1;
11632
11633   S (mp);
11634   W (ret);
11635   return ret;
11636 }
11637
11638 static int
11639 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11640 {
11641   unformat_input_t *i = vam->input;
11642   u32 sw_if_index;
11643   u8 sw_if_index_set = 0;
11644   u64 new_local_cookie = 0;
11645   u64 new_remote_cookie = 0;
11646   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11647   int ret;
11648
11649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11650     {
11651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11652         sw_if_index_set = 1;
11653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11654         sw_if_index_set = 1;
11655       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11656         ;
11657       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11658         ;
11659       else
11660         break;
11661     }
11662
11663   if (sw_if_index_set == 0)
11664     {
11665       errmsg ("missing interface name or sw_if_index");
11666       return -99;
11667     }
11668
11669   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11670
11671   mp->sw_if_index = ntohl (sw_if_index);
11672   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11673   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11674
11675   S (mp);
11676   W (ret);
11677   return ret;
11678 }
11679
11680 static int
11681 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11682 {
11683   unformat_input_t *i = vam->input;
11684   vl_api_l2tpv3_interface_enable_disable_t *mp;
11685   u32 sw_if_index;
11686   u8 sw_if_index_set = 0;
11687   u8 enable_disable = 1;
11688   int ret;
11689
11690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11691     {
11692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11693         sw_if_index_set = 1;
11694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11695         sw_if_index_set = 1;
11696       else if (unformat (i, "enable"))
11697         enable_disable = 1;
11698       else if (unformat (i, "disable"))
11699         enable_disable = 0;
11700       else
11701         break;
11702     }
11703
11704   if (sw_if_index_set == 0)
11705     {
11706       errmsg ("missing interface name or sw_if_index");
11707       return -99;
11708     }
11709
11710   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11711
11712   mp->sw_if_index = ntohl (sw_if_index);
11713   mp->enable_disable = enable_disable;
11714
11715   S (mp);
11716   W (ret);
11717   return ret;
11718 }
11719
11720 static int
11721 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11722 {
11723   unformat_input_t *i = vam->input;
11724   vl_api_l2tpv3_set_lookup_key_t *mp;
11725   u8 key = ~0;
11726   int ret;
11727
11728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11729     {
11730       if (unformat (i, "lookup_v6_src"))
11731         key = L2T_LOOKUP_SRC_ADDRESS;
11732       else if (unformat (i, "lookup_v6_dst"))
11733         key = L2T_LOOKUP_DST_ADDRESS;
11734       else if (unformat (i, "lookup_session_id"))
11735         key = L2T_LOOKUP_SESSION_ID;
11736       else
11737         break;
11738     }
11739
11740   if (key == (u8) ~ 0)
11741     {
11742       errmsg ("l2tp session lookup key unset");
11743       return -99;
11744     }
11745
11746   M (L2TPV3_SET_LOOKUP_KEY, mp);
11747
11748   mp->key = key;
11749
11750   S (mp);
11751   W (ret);
11752   return ret;
11753 }
11754
11755 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11756   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11757 {
11758   vat_main_t *vam = &vat_main;
11759
11760   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11761          format_ip6_address, mp->our_address,
11762          format_ip6_address, mp->client_address,
11763          clib_net_to_host_u32 (mp->sw_if_index));
11764
11765   print (vam->ofp,
11766          "   local cookies %016llx %016llx remote cookie %016llx",
11767          clib_net_to_host_u64 (mp->local_cookie[0]),
11768          clib_net_to_host_u64 (mp->local_cookie[1]),
11769          clib_net_to_host_u64 (mp->remote_cookie));
11770
11771   print (vam->ofp, "   local session-id %d remote session-id %d",
11772          clib_net_to_host_u32 (mp->local_session_id),
11773          clib_net_to_host_u32 (mp->remote_session_id));
11774
11775   print (vam->ofp, "   l2 specific sublayer %s\n",
11776          mp->l2_sublayer_present ? "preset" : "absent");
11777
11778 }
11779
11780 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11781   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11782 {
11783   vat_main_t *vam = &vat_main;
11784   vat_json_node_t *node = NULL;
11785   struct in6_addr addr;
11786
11787   if (VAT_JSON_ARRAY != vam->json_tree.type)
11788     {
11789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11790       vat_json_init_array (&vam->json_tree);
11791     }
11792   node = vat_json_array_add (&vam->json_tree);
11793
11794   vat_json_init_object (node);
11795
11796   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11797   vat_json_object_add_ip6 (node, "our_address", addr);
11798   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11799   vat_json_object_add_ip6 (node, "client_address", addr);
11800
11801   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11802   vat_json_init_array (lc);
11803   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11804   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11805   vat_json_object_add_uint (node, "remote_cookie",
11806                             clib_net_to_host_u64 (mp->remote_cookie));
11807
11808   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11809   vat_json_object_add_uint (node, "local_session_id",
11810                             clib_net_to_host_u32 (mp->local_session_id));
11811   vat_json_object_add_uint (node, "remote_session_id",
11812                             clib_net_to_host_u32 (mp->remote_session_id));
11813   vat_json_object_add_string_copy (node, "l2_sublayer",
11814                                    mp->l2_sublayer_present ? (u8 *) "present"
11815                                    : (u8 *) "absent");
11816 }
11817
11818 static int
11819 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11820 {
11821   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11822   vl_api_control_ping_t *mp_ping;
11823   int ret;
11824
11825   /* Get list of l2tpv3-tunnel interfaces */
11826   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11827   S (mp);
11828
11829   /* Use a control ping for synchronization */
11830   MPING (CONTROL_PING, mp_ping);
11831   S (mp_ping);
11832
11833   W (ret);
11834   return ret;
11835 }
11836
11837
11838 static void vl_api_sw_interface_tap_details_t_handler
11839   (vl_api_sw_interface_tap_details_t * mp)
11840 {
11841   vat_main_t *vam = &vat_main;
11842
11843   print (vam->ofp, "%-16s %d",
11844          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11845 }
11846
11847 static void vl_api_sw_interface_tap_details_t_handler_json
11848   (vl_api_sw_interface_tap_details_t * mp)
11849 {
11850   vat_main_t *vam = &vat_main;
11851   vat_json_node_t *node = NULL;
11852
11853   if (VAT_JSON_ARRAY != vam->json_tree.type)
11854     {
11855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11856       vat_json_init_array (&vam->json_tree);
11857     }
11858   node = vat_json_array_add (&vam->json_tree);
11859
11860   vat_json_init_object (node);
11861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11862   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11863 }
11864
11865 static int
11866 api_sw_interface_tap_dump (vat_main_t * vam)
11867 {
11868   vl_api_sw_interface_tap_dump_t *mp;
11869   vl_api_control_ping_t *mp_ping;
11870   int ret;
11871
11872   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11873   /* Get list of tap interfaces */
11874   M (SW_INTERFACE_TAP_DUMP, mp);
11875   S (mp);
11876
11877   /* Use a control ping for synchronization */
11878   MPING (CONTROL_PING, mp_ping);
11879   S (mp_ping);
11880
11881   W (ret);
11882   return ret;
11883 }
11884
11885 static uword unformat_vxlan_decap_next
11886   (unformat_input_t * input, va_list * args)
11887 {
11888   u32 *result = va_arg (*args, u32 *);
11889   u32 tmp;
11890
11891   if (unformat (input, "l2"))
11892     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11893   else if (unformat (input, "%d", &tmp))
11894     *result = tmp;
11895   else
11896     return 0;
11897   return 1;
11898 }
11899
11900 static int
11901 api_vxlan_add_del_tunnel (vat_main_t * vam)
11902 {
11903   unformat_input_t *line_input = vam->input;
11904   vl_api_vxlan_add_del_tunnel_t *mp;
11905   ip46_address_t src, dst;
11906   u8 is_add = 1;
11907   u8 ipv4_set = 0, ipv6_set = 0;
11908   u8 src_set = 0;
11909   u8 dst_set = 0;
11910   u8 grp_set = 0;
11911   u32 mcast_sw_if_index = ~0;
11912   u32 encap_vrf_id = 0;
11913   u32 decap_next_index = ~0;
11914   u32 vni = 0;
11915   int ret;
11916
11917   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11918   memset (&src, 0, sizeof src);
11919   memset (&dst, 0, sizeof dst);
11920
11921   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11922     {
11923       if (unformat (line_input, "del"))
11924         is_add = 0;
11925       else
11926         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11927         {
11928           ipv4_set = 1;
11929           src_set = 1;
11930         }
11931       else
11932         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11933         {
11934           ipv4_set = 1;
11935           dst_set = 1;
11936         }
11937       else
11938         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11939         {
11940           ipv6_set = 1;
11941           src_set = 1;
11942         }
11943       else
11944         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11945         {
11946           ipv6_set = 1;
11947           dst_set = 1;
11948         }
11949       else if (unformat (line_input, "group %U %U",
11950                          unformat_ip4_address, &dst.ip4,
11951                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11952         {
11953           grp_set = dst_set = 1;
11954           ipv4_set = 1;
11955         }
11956       else if (unformat (line_input, "group %U",
11957                          unformat_ip4_address, &dst.ip4))
11958         {
11959           grp_set = dst_set = 1;
11960           ipv4_set = 1;
11961         }
11962       else if (unformat (line_input, "group %U %U",
11963                          unformat_ip6_address, &dst.ip6,
11964                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11965         {
11966           grp_set = dst_set = 1;
11967           ipv6_set = 1;
11968         }
11969       else if (unformat (line_input, "group %U",
11970                          unformat_ip6_address, &dst.ip6))
11971         {
11972           grp_set = dst_set = 1;
11973           ipv6_set = 1;
11974         }
11975       else
11976         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11977         ;
11978       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11979         ;
11980       else if (unformat (line_input, "decap-next %U",
11981                          unformat_vxlan_decap_next, &decap_next_index))
11982         ;
11983       else if (unformat (line_input, "vni %d", &vni))
11984         ;
11985       else
11986         {
11987           errmsg ("parse error '%U'", format_unformat_error, line_input);
11988           return -99;
11989         }
11990     }
11991
11992   if (src_set == 0)
11993     {
11994       errmsg ("tunnel src address not specified");
11995       return -99;
11996     }
11997   if (dst_set == 0)
11998     {
11999       errmsg ("tunnel dst address not specified");
12000       return -99;
12001     }
12002
12003   if (grp_set && !ip46_address_is_multicast (&dst))
12004     {
12005       errmsg ("tunnel group address not multicast");
12006       return -99;
12007     }
12008   if (grp_set && mcast_sw_if_index == ~0)
12009     {
12010       errmsg ("tunnel nonexistent multicast device");
12011       return -99;
12012     }
12013   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12014     {
12015       errmsg ("tunnel dst address must be unicast");
12016       return -99;
12017     }
12018
12019
12020   if (ipv4_set && ipv6_set)
12021     {
12022       errmsg ("both IPv4 and IPv6 addresses specified");
12023       return -99;
12024     }
12025
12026   if ((vni == 0) || (vni >> 24))
12027     {
12028       errmsg ("vni not specified or out of range");
12029       return -99;
12030     }
12031
12032   M (VXLAN_ADD_DEL_TUNNEL, mp);
12033
12034   if (ipv6_set)
12035     {
12036       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12037       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12038     }
12039   else
12040     {
12041       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12042       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12043     }
12044   mp->encap_vrf_id = ntohl (encap_vrf_id);
12045   mp->decap_next_index = ntohl (decap_next_index);
12046   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12047   mp->vni = ntohl (vni);
12048   mp->is_add = is_add;
12049   mp->is_ipv6 = ipv6_set;
12050
12051   S (mp);
12052   W (ret);
12053   return ret;
12054 }
12055
12056 static void vl_api_vxlan_tunnel_details_t_handler
12057   (vl_api_vxlan_tunnel_details_t * mp)
12058 {
12059   vat_main_t *vam = &vat_main;
12060   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12061   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12062
12063   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12064          ntohl (mp->sw_if_index),
12065          format_ip46_address, &src, IP46_TYPE_ANY,
12066          format_ip46_address, &dst, IP46_TYPE_ANY,
12067          ntohl (mp->encap_vrf_id),
12068          ntohl (mp->decap_next_index), ntohl (mp->vni),
12069          ntohl (mp->mcast_sw_if_index));
12070 }
12071
12072 static void vl_api_vxlan_tunnel_details_t_handler_json
12073   (vl_api_vxlan_tunnel_details_t * mp)
12074 {
12075   vat_main_t *vam = &vat_main;
12076   vat_json_node_t *node = NULL;
12077
12078   if (VAT_JSON_ARRAY != vam->json_tree.type)
12079     {
12080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12081       vat_json_init_array (&vam->json_tree);
12082     }
12083   node = vat_json_array_add (&vam->json_tree);
12084
12085   vat_json_init_object (node);
12086   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12087   if (mp->is_ipv6)
12088     {
12089       struct in6_addr ip6;
12090
12091       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12092       vat_json_object_add_ip6 (node, "src_address", ip6);
12093       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12094       vat_json_object_add_ip6 (node, "dst_address", ip6);
12095     }
12096   else
12097     {
12098       struct in_addr ip4;
12099
12100       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12101       vat_json_object_add_ip4 (node, "src_address", ip4);
12102       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12103       vat_json_object_add_ip4 (node, "dst_address", ip4);
12104     }
12105   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12106   vat_json_object_add_uint (node, "decap_next_index",
12107                             ntohl (mp->decap_next_index));
12108   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12109   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12110   vat_json_object_add_uint (node, "mcast_sw_if_index",
12111                             ntohl (mp->mcast_sw_if_index));
12112 }
12113
12114 static int
12115 api_vxlan_tunnel_dump (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_vxlan_tunnel_dump_t *mp;
12119   vl_api_control_ping_t *mp_ping;
12120   u32 sw_if_index;
12121   u8 sw_if_index_set = 0;
12122   int ret;
12123
12124   /* Parse args required to build the message */
12125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (i, "sw_if_index %d", &sw_if_index))
12128         sw_if_index_set = 1;
12129       else
12130         break;
12131     }
12132
12133   if (sw_if_index_set == 0)
12134     {
12135       sw_if_index = ~0;
12136     }
12137
12138   if (!vam->json_output)
12139     {
12140       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12141              "sw_if_index", "src_address", "dst_address",
12142              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12143     }
12144
12145   /* Get list of vxlan-tunnel interfaces */
12146   M (VXLAN_TUNNEL_DUMP, mp);
12147
12148   mp->sw_if_index = htonl (sw_if_index);
12149
12150   S (mp);
12151
12152   /* Use a control ping for synchronization */
12153   MPING (CONTROL_PING, mp_ping);
12154   S (mp_ping);
12155
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static uword unformat_geneve_decap_next
12161   (unformat_input_t * input, va_list * args)
12162 {
12163   u32 *result = va_arg (*args, u32 *);
12164   u32 tmp;
12165
12166   if (unformat (input, "l2"))
12167     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12168   else if (unformat (input, "%d", &tmp))
12169     *result = tmp;
12170   else
12171     return 0;
12172   return 1;
12173 }
12174
12175 static int
12176 api_geneve_add_del_tunnel (vat_main_t * vam)
12177 {
12178   unformat_input_t *line_input = vam->input;
12179   vl_api_geneve_add_del_tunnel_t *mp;
12180   ip46_address_t src, dst;
12181   u8 is_add = 1;
12182   u8 ipv4_set = 0, ipv6_set = 0;
12183   u8 src_set = 0;
12184   u8 dst_set = 0;
12185   u8 grp_set = 0;
12186   u32 mcast_sw_if_index = ~0;
12187   u32 encap_vrf_id = 0;
12188   u32 decap_next_index = ~0;
12189   u32 vni = 0;
12190   int ret;
12191
12192   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12193   memset (&src, 0, sizeof src);
12194   memset (&dst, 0, sizeof dst);
12195
12196   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12197     {
12198       if (unformat (line_input, "del"))
12199         is_add = 0;
12200       else
12201         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12202         {
12203           ipv4_set = 1;
12204           src_set = 1;
12205         }
12206       else
12207         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12208         {
12209           ipv4_set = 1;
12210           dst_set = 1;
12211         }
12212       else
12213         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12214         {
12215           ipv6_set = 1;
12216           src_set = 1;
12217         }
12218       else
12219         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12220         {
12221           ipv6_set = 1;
12222           dst_set = 1;
12223         }
12224       else if (unformat (line_input, "group %U %U",
12225                          unformat_ip4_address, &dst.ip4,
12226                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12227         {
12228           grp_set = dst_set = 1;
12229           ipv4_set = 1;
12230         }
12231       else if (unformat (line_input, "group %U",
12232                          unformat_ip4_address, &dst.ip4))
12233         {
12234           grp_set = dst_set = 1;
12235           ipv4_set = 1;
12236         }
12237       else if (unformat (line_input, "group %U %U",
12238                          unformat_ip6_address, &dst.ip6,
12239                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12240         {
12241           grp_set = dst_set = 1;
12242           ipv6_set = 1;
12243         }
12244       else if (unformat (line_input, "group %U",
12245                          unformat_ip6_address, &dst.ip6))
12246         {
12247           grp_set = dst_set = 1;
12248           ipv6_set = 1;
12249         }
12250       else
12251         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12252         ;
12253       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12254         ;
12255       else if (unformat (line_input, "decap-next %U",
12256                          unformat_geneve_decap_next, &decap_next_index))
12257         ;
12258       else if (unformat (line_input, "vni %d", &vni))
12259         ;
12260       else
12261         {
12262           errmsg ("parse error '%U'", format_unformat_error, line_input);
12263           return -99;
12264         }
12265     }
12266
12267   if (src_set == 0)
12268     {
12269       errmsg ("tunnel src address not specified");
12270       return -99;
12271     }
12272   if (dst_set == 0)
12273     {
12274       errmsg ("tunnel dst address not specified");
12275       return -99;
12276     }
12277
12278   if (grp_set && !ip46_address_is_multicast (&dst))
12279     {
12280       errmsg ("tunnel group address not multicast");
12281       return -99;
12282     }
12283   if (grp_set && mcast_sw_if_index == ~0)
12284     {
12285       errmsg ("tunnel nonexistent multicast device");
12286       return -99;
12287     }
12288   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12289     {
12290       errmsg ("tunnel dst address must be unicast");
12291       return -99;
12292     }
12293
12294
12295   if (ipv4_set && ipv6_set)
12296     {
12297       errmsg ("both IPv4 and IPv6 addresses specified");
12298       return -99;
12299     }
12300
12301   if ((vni == 0) || (vni >> 24))
12302     {
12303       errmsg ("vni not specified or out of range");
12304       return -99;
12305     }
12306
12307   M (GENEVE_ADD_DEL_TUNNEL, mp);
12308
12309   if (ipv6_set)
12310     {
12311       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12312       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12313     }
12314   else
12315     {
12316       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12317       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12318     }
12319   mp->encap_vrf_id = ntohl (encap_vrf_id);
12320   mp->decap_next_index = ntohl (decap_next_index);
12321   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12322   mp->vni = ntohl (vni);
12323   mp->is_add = is_add;
12324   mp->is_ipv6 = ipv6_set;
12325
12326   S (mp);
12327   W (ret);
12328   return ret;
12329 }
12330
12331 static void vl_api_geneve_tunnel_details_t_handler
12332   (vl_api_geneve_tunnel_details_t * mp)
12333 {
12334   vat_main_t *vam = &vat_main;
12335   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12336   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12337
12338   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12339          ntohl (mp->sw_if_index),
12340          format_ip46_address, &src, IP46_TYPE_ANY,
12341          format_ip46_address, &dst, IP46_TYPE_ANY,
12342          ntohl (mp->encap_vrf_id),
12343          ntohl (mp->decap_next_index), ntohl (mp->vni),
12344          ntohl (mp->mcast_sw_if_index));
12345 }
12346
12347 static void vl_api_geneve_tunnel_details_t_handler_json
12348   (vl_api_geneve_tunnel_details_t * mp)
12349 {
12350   vat_main_t *vam = &vat_main;
12351   vat_json_node_t *node = NULL;
12352
12353   if (VAT_JSON_ARRAY != vam->json_tree.type)
12354     {
12355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12356       vat_json_init_array (&vam->json_tree);
12357     }
12358   node = vat_json_array_add (&vam->json_tree);
12359
12360   vat_json_init_object (node);
12361   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12362   if (mp->is_ipv6)
12363     {
12364       struct in6_addr ip6;
12365
12366       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12367       vat_json_object_add_ip6 (node, "src_address", ip6);
12368       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12369       vat_json_object_add_ip6 (node, "dst_address", ip6);
12370     }
12371   else
12372     {
12373       struct in_addr ip4;
12374
12375       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12376       vat_json_object_add_ip4 (node, "src_address", ip4);
12377       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12378       vat_json_object_add_ip4 (node, "dst_address", ip4);
12379     }
12380   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12381   vat_json_object_add_uint (node, "decap_next_index",
12382                             ntohl (mp->decap_next_index));
12383   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12384   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12385   vat_json_object_add_uint (node, "mcast_sw_if_index",
12386                             ntohl (mp->mcast_sw_if_index));
12387 }
12388
12389 static int
12390 api_geneve_tunnel_dump (vat_main_t * vam)
12391 {
12392   unformat_input_t *i = vam->input;
12393   vl_api_geneve_tunnel_dump_t *mp;
12394   vl_api_control_ping_t *mp_ping;
12395   u32 sw_if_index;
12396   u8 sw_if_index_set = 0;
12397   int ret;
12398
12399   /* Parse args required to build the message */
12400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12401     {
12402       if (unformat (i, "sw_if_index %d", &sw_if_index))
12403         sw_if_index_set = 1;
12404       else
12405         break;
12406     }
12407
12408   if (sw_if_index_set == 0)
12409     {
12410       sw_if_index = ~0;
12411     }
12412
12413   if (!vam->json_output)
12414     {
12415       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12416              "sw_if_index", "local_address", "remote_address",
12417              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12418     }
12419
12420   /* Get list of geneve-tunnel interfaces */
12421   M (GENEVE_TUNNEL_DUMP, mp);
12422
12423   mp->sw_if_index = htonl (sw_if_index);
12424
12425   S (mp);
12426
12427   /* Use a control ping for synchronization */
12428   M (CONTROL_PING, mp_ping);
12429   S (mp_ping);
12430
12431   W (ret);
12432   return ret;
12433 }
12434
12435 static int
12436 api_gre_add_del_tunnel (vat_main_t * vam)
12437 {
12438   unformat_input_t *line_input = vam->input;
12439   vl_api_gre_add_del_tunnel_t *mp;
12440   ip4_address_t src4, dst4;
12441   ip6_address_t src6, dst6;
12442   u8 is_add = 1;
12443   u8 ipv4_set = 0;
12444   u8 ipv6_set = 0;
12445   u8 teb = 0;
12446   u8 src_set = 0;
12447   u8 dst_set = 0;
12448   u32 outer_fib_id = 0;
12449   int ret;
12450
12451   memset (&src4, 0, sizeof src4);
12452   memset (&dst4, 0, sizeof dst4);
12453   memset (&src6, 0, sizeof src6);
12454   memset (&dst6, 0, sizeof dst6);
12455
12456   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12457     {
12458       if (unformat (line_input, "del"))
12459         is_add = 0;
12460       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12461         {
12462           src_set = 1;
12463           ipv4_set = 1;
12464         }
12465       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12466         {
12467           dst_set = 1;
12468           ipv4_set = 1;
12469         }
12470       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12471         {
12472           src_set = 1;
12473           ipv6_set = 1;
12474         }
12475       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12476         {
12477           dst_set = 1;
12478           ipv6_set = 1;
12479         }
12480       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12481         ;
12482       else if (unformat (line_input, "teb"))
12483         teb = 1;
12484       else
12485         {
12486           errmsg ("parse error '%U'", format_unformat_error, line_input);
12487           return -99;
12488         }
12489     }
12490
12491   if (src_set == 0)
12492     {
12493       errmsg ("tunnel src address not specified");
12494       return -99;
12495     }
12496   if (dst_set == 0)
12497     {
12498       errmsg ("tunnel dst address not specified");
12499       return -99;
12500     }
12501   if (ipv4_set && ipv6_set)
12502     {
12503       errmsg ("both IPv4 and IPv6 addresses specified");
12504       return -99;
12505     }
12506
12507
12508   M (GRE_ADD_DEL_TUNNEL, mp);
12509
12510   if (ipv4_set)
12511     {
12512       clib_memcpy (&mp->src_address, &src4, 4);
12513       clib_memcpy (&mp->dst_address, &dst4, 4);
12514     }
12515   else
12516     {
12517       clib_memcpy (&mp->src_address, &src6, 16);
12518       clib_memcpy (&mp->dst_address, &dst6, 16);
12519     }
12520   mp->outer_fib_id = ntohl (outer_fib_id);
12521   mp->is_add = is_add;
12522   mp->teb = teb;
12523   mp->is_ipv6 = ipv6_set;
12524
12525   S (mp);
12526   W (ret);
12527   return ret;
12528 }
12529
12530 static void vl_api_gre_tunnel_details_t_handler
12531   (vl_api_gre_tunnel_details_t * mp)
12532 {
12533   vat_main_t *vam = &vat_main;
12534   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12535   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12536
12537   print (vam->ofp, "%11d%24U%24U%6d%14d",
12538          ntohl (mp->sw_if_index),
12539          format_ip46_address, &src, IP46_TYPE_ANY,
12540          format_ip46_address, &dst, IP46_TYPE_ANY,
12541          mp->teb, ntohl (mp->outer_fib_id));
12542 }
12543
12544 static void vl_api_gre_tunnel_details_t_handler_json
12545   (vl_api_gre_tunnel_details_t * mp)
12546 {
12547   vat_main_t *vam = &vat_main;
12548   vat_json_node_t *node = NULL;
12549   struct in_addr ip4;
12550   struct in6_addr ip6;
12551
12552   if (VAT_JSON_ARRAY != vam->json_tree.type)
12553     {
12554       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12555       vat_json_init_array (&vam->json_tree);
12556     }
12557   node = vat_json_array_add (&vam->json_tree);
12558
12559   vat_json_init_object (node);
12560   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12561   if (!mp->is_ipv6)
12562     {
12563       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12564       vat_json_object_add_ip4 (node, "src_address", ip4);
12565       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12566       vat_json_object_add_ip4 (node, "dst_address", ip4);
12567     }
12568   else
12569     {
12570       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12571       vat_json_object_add_ip6 (node, "src_address", ip6);
12572       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12573       vat_json_object_add_ip6 (node, "dst_address", ip6);
12574     }
12575   vat_json_object_add_uint (node, "teb", mp->teb);
12576   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12577   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12578 }
12579
12580 static int
12581 api_gre_tunnel_dump (vat_main_t * vam)
12582 {
12583   unformat_input_t *i = vam->input;
12584   vl_api_gre_tunnel_dump_t *mp;
12585   vl_api_control_ping_t *mp_ping;
12586   u32 sw_if_index;
12587   u8 sw_if_index_set = 0;
12588   int ret;
12589
12590   /* Parse args required to build the message */
12591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12592     {
12593       if (unformat (i, "sw_if_index %d", &sw_if_index))
12594         sw_if_index_set = 1;
12595       else
12596         break;
12597     }
12598
12599   if (sw_if_index_set == 0)
12600     {
12601       sw_if_index = ~0;
12602     }
12603
12604   if (!vam->json_output)
12605     {
12606       print (vam->ofp, "%11s%24s%24s%6s%14s",
12607              "sw_if_index", "src_address", "dst_address", "teb",
12608              "outer_fib_id");
12609     }
12610
12611   /* Get list of gre-tunnel interfaces */
12612   M (GRE_TUNNEL_DUMP, mp);
12613
12614   mp->sw_if_index = htonl (sw_if_index);
12615
12616   S (mp);
12617
12618   /* Use a control ping for synchronization */
12619   MPING (CONTROL_PING, mp_ping);
12620   S (mp_ping);
12621
12622   W (ret);
12623   return ret;
12624 }
12625
12626 static int
12627 api_l2_fib_clear_table (vat_main_t * vam)
12628 {
12629 //  unformat_input_t * i = vam->input;
12630   vl_api_l2_fib_clear_table_t *mp;
12631   int ret;
12632
12633   M (L2_FIB_CLEAR_TABLE, mp);
12634
12635   S (mp);
12636   W (ret);
12637   return ret;
12638 }
12639
12640 static int
12641 api_l2_interface_efp_filter (vat_main_t * vam)
12642 {
12643   unformat_input_t *i = vam->input;
12644   vl_api_l2_interface_efp_filter_t *mp;
12645   u32 sw_if_index;
12646   u8 enable = 1;
12647   u8 sw_if_index_set = 0;
12648   int ret;
12649
12650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12651     {
12652       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12653         sw_if_index_set = 1;
12654       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12655         sw_if_index_set = 1;
12656       else if (unformat (i, "enable"))
12657         enable = 1;
12658       else if (unformat (i, "disable"))
12659         enable = 0;
12660       else
12661         {
12662           clib_warning ("parse error '%U'", format_unformat_error, i);
12663           return -99;
12664         }
12665     }
12666
12667   if (sw_if_index_set == 0)
12668     {
12669       errmsg ("missing sw_if_index");
12670       return -99;
12671     }
12672
12673   M (L2_INTERFACE_EFP_FILTER, mp);
12674
12675   mp->sw_if_index = ntohl (sw_if_index);
12676   mp->enable_disable = enable;
12677
12678   S (mp);
12679   W (ret);
12680   return ret;
12681 }
12682
12683 #define foreach_vtr_op                          \
12684 _("disable",  L2_VTR_DISABLED)                  \
12685 _("push-1",  L2_VTR_PUSH_1)                     \
12686 _("push-2",  L2_VTR_PUSH_2)                     \
12687 _("pop-1",  L2_VTR_POP_1)                       \
12688 _("pop-2",  L2_VTR_POP_2)                       \
12689 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12690 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12691 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12692 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12693
12694 static int
12695 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12696 {
12697   unformat_input_t *i = vam->input;
12698   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12699   u32 sw_if_index;
12700   u8 sw_if_index_set = 0;
12701   u8 vtr_op_set = 0;
12702   u32 vtr_op = 0;
12703   u32 push_dot1q = 1;
12704   u32 tag1 = ~0;
12705   u32 tag2 = ~0;
12706   int ret;
12707
12708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12709     {
12710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12711         sw_if_index_set = 1;
12712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12713         sw_if_index_set = 1;
12714       else if (unformat (i, "vtr_op %d", &vtr_op))
12715         vtr_op_set = 1;
12716 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12717       foreach_vtr_op
12718 #undef _
12719         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12720         ;
12721       else if (unformat (i, "tag1 %d", &tag1))
12722         ;
12723       else if (unformat (i, "tag2 %d", &tag2))
12724         ;
12725       else
12726         {
12727           clib_warning ("parse error '%U'", format_unformat_error, i);
12728           return -99;
12729         }
12730     }
12731
12732   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12733     {
12734       errmsg ("missing vtr operation or sw_if_index");
12735       return -99;
12736     }
12737
12738   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12739   mp->sw_if_index = ntohl (sw_if_index);
12740   mp->vtr_op = ntohl (vtr_op);
12741   mp->push_dot1q = ntohl (push_dot1q);
12742   mp->tag1 = ntohl (tag1);
12743   mp->tag2 = ntohl (tag2);
12744
12745   S (mp);
12746   W (ret);
12747   return ret;
12748 }
12749
12750 static int
12751 api_create_vhost_user_if (vat_main_t * vam)
12752 {
12753   unformat_input_t *i = vam->input;
12754   vl_api_create_vhost_user_if_t *mp;
12755   u8 *file_name;
12756   u8 is_server = 0;
12757   u8 file_name_set = 0;
12758   u32 custom_dev_instance = ~0;
12759   u8 hwaddr[6];
12760   u8 use_custom_mac = 0;
12761   u8 *tag = 0;
12762   int ret;
12763
12764   /* Shut up coverity */
12765   memset (hwaddr, 0, sizeof (hwaddr));
12766
12767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (i, "socket %s", &file_name))
12770         {
12771           file_name_set = 1;
12772         }
12773       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12774         ;
12775       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12776         use_custom_mac = 1;
12777       else if (unformat (i, "server"))
12778         is_server = 1;
12779       else if (unformat (i, "tag %s", &tag))
12780         ;
12781       else
12782         break;
12783     }
12784
12785   if (file_name_set == 0)
12786     {
12787       errmsg ("missing socket file name");
12788       return -99;
12789     }
12790
12791   if (vec_len (file_name) > 255)
12792     {
12793       errmsg ("socket file name too long");
12794       return -99;
12795     }
12796   vec_add1 (file_name, 0);
12797
12798   M (CREATE_VHOST_USER_IF, mp);
12799
12800   mp->is_server = is_server;
12801   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12802   vec_free (file_name);
12803   if (custom_dev_instance != ~0)
12804     {
12805       mp->renumber = 1;
12806       mp->custom_dev_instance = ntohl (custom_dev_instance);
12807     }
12808   mp->use_custom_mac = use_custom_mac;
12809   clib_memcpy (mp->mac_address, hwaddr, 6);
12810   if (tag)
12811     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12812   vec_free (tag);
12813
12814   S (mp);
12815   W (ret);
12816   return ret;
12817 }
12818
12819 static int
12820 api_modify_vhost_user_if (vat_main_t * vam)
12821 {
12822   unformat_input_t *i = vam->input;
12823   vl_api_modify_vhost_user_if_t *mp;
12824   u8 *file_name;
12825   u8 is_server = 0;
12826   u8 file_name_set = 0;
12827   u32 custom_dev_instance = ~0;
12828   u8 sw_if_index_set = 0;
12829   u32 sw_if_index = (u32) ~ 0;
12830   int ret;
12831
12832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12833     {
12834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12835         sw_if_index_set = 1;
12836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12837         sw_if_index_set = 1;
12838       else if (unformat (i, "socket %s", &file_name))
12839         {
12840           file_name_set = 1;
12841         }
12842       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12843         ;
12844       else if (unformat (i, "server"))
12845         is_server = 1;
12846       else
12847         break;
12848     }
12849
12850   if (sw_if_index_set == 0)
12851     {
12852       errmsg ("missing sw_if_index or interface name");
12853       return -99;
12854     }
12855
12856   if (file_name_set == 0)
12857     {
12858       errmsg ("missing socket file name");
12859       return -99;
12860     }
12861
12862   if (vec_len (file_name) > 255)
12863     {
12864       errmsg ("socket file name too long");
12865       return -99;
12866     }
12867   vec_add1 (file_name, 0);
12868
12869   M (MODIFY_VHOST_USER_IF, mp);
12870
12871   mp->sw_if_index = ntohl (sw_if_index);
12872   mp->is_server = is_server;
12873   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12874   vec_free (file_name);
12875   if (custom_dev_instance != ~0)
12876     {
12877       mp->renumber = 1;
12878       mp->custom_dev_instance = ntohl (custom_dev_instance);
12879     }
12880
12881   S (mp);
12882   W (ret);
12883   return ret;
12884 }
12885
12886 static int
12887 api_delete_vhost_user_if (vat_main_t * vam)
12888 {
12889   unformat_input_t *i = vam->input;
12890   vl_api_delete_vhost_user_if_t *mp;
12891   u32 sw_if_index = ~0;
12892   u8 sw_if_index_set = 0;
12893   int ret;
12894
12895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12896     {
12897       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12898         sw_if_index_set = 1;
12899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12900         sw_if_index_set = 1;
12901       else
12902         break;
12903     }
12904
12905   if (sw_if_index_set == 0)
12906     {
12907       errmsg ("missing sw_if_index or interface name");
12908       return -99;
12909     }
12910
12911
12912   M (DELETE_VHOST_USER_IF, mp);
12913
12914   mp->sw_if_index = ntohl (sw_if_index);
12915
12916   S (mp);
12917   W (ret);
12918   return ret;
12919 }
12920
12921 static void vl_api_sw_interface_vhost_user_details_t_handler
12922   (vl_api_sw_interface_vhost_user_details_t * mp)
12923 {
12924   vat_main_t *vam = &vat_main;
12925
12926   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12927          (char *) mp->interface_name,
12928          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12929          clib_net_to_host_u64 (mp->features), mp->is_server,
12930          ntohl (mp->num_regions), (char *) mp->sock_filename);
12931   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12932 }
12933
12934 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12935   (vl_api_sw_interface_vhost_user_details_t * mp)
12936 {
12937   vat_main_t *vam = &vat_main;
12938   vat_json_node_t *node = NULL;
12939
12940   if (VAT_JSON_ARRAY != vam->json_tree.type)
12941     {
12942       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12943       vat_json_init_array (&vam->json_tree);
12944     }
12945   node = vat_json_array_add (&vam->json_tree);
12946
12947   vat_json_init_object (node);
12948   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12949   vat_json_object_add_string_copy (node, "interface_name",
12950                                    mp->interface_name);
12951   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12952                             ntohl (mp->virtio_net_hdr_sz));
12953   vat_json_object_add_uint (node, "features",
12954                             clib_net_to_host_u64 (mp->features));
12955   vat_json_object_add_uint (node, "is_server", mp->is_server);
12956   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12957   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12958   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12959 }
12960
12961 static int
12962 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12963 {
12964   vl_api_sw_interface_vhost_user_dump_t *mp;
12965   vl_api_control_ping_t *mp_ping;
12966   int ret;
12967   print (vam->ofp,
12968          "Interface name            idx hdr_sz features server regions filename");
12969
12970   /* Get list of vhost-user interfaces */
12971   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12972   S (mp);
12973
12974   /* Use a control ping for synchronization */
12975   MPING (CONTROL_PING, mp_ping);
12976   S (mp_ping);
12977
12978   W (ret);
12979   return ret;
12980 }
12981
12982 static int
12983 api_show_version (vat_main_t * vam)
12984 {
12985   vl_api_show_version_t *mp;
12986   int ret;
12987
12988   M (SHOW_VERSION, mp);
12989
12990   S (mp);
12991   W (ret);
12992   return ret;
12993 }
12994
12995
12996 static int
12997 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12998 {
12999   unformat_input_t *line_input = vam->input;
13000   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13001   ip4_address_t local4, remote4;
13002   ip6_address_t local6, remote6;
13003   u8 is_add = 1;
13004   u8 ipv4_set = 0, ipv6_set = 0;
13005   u8 local_set = 0;
13006   u8 remote_set = 0;
13007   u8 grp_set = 0;
13008   u32 mcast_sw_if_index = ~0;
13009   u32 encap_vrf_id = 0;
13010   u32 decap_vrf_id = 0;
13011   u8 protocol = ~0;
13012   u32 vni;
13013   u8 vni_set = 0;
13014   int ret;
13015
13016   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13017   memset (&local4, 0, sizeof local4);
13018   memset (&remote4, 0, sizeof remote4);
13019   memset (&local6, 0, sizeof local6);
13020   memset (&remote6, 0, sizeof remote6);
13021
13022   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13023     {
13024       if (unformat (line_input, "del"))
13025         is_add = 0;
13026       else if (unformat (line_input, "local %U",
13027                          unformat_ip4_address, &local4))
13028         {
13029           local_set = 1;
13030           ipv4_set = 1;
13031         }
13032       else if (unformat (line_input, "remote %U",
13033                          unformat_ip4_address, &remote4))
13034         {
13035           remote_set = 1;
13036           ipv4_set = 1;
13037         }
13038       else if (unformat (line_input, "local %U",
13039                          unformat_ip6_address, &local6))
13040         {
13041           local_set = 1;
13042           ipv6_set = 1;
13043         }
13044       else if (unformat (line_input, "remote %U",
13045                          unformat_ip6_address, &remote6))
13046         {
13047           remote_set = 1;
13048           ipv6_set = 1;
13049         }
13050       else if (unformat (line_input, "group %U %U",
13051                          unformat_ip4_address, &remote4,
13052                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13053         {
13054           grp_set = remote_set = 1;
13055           ipv4_set = 1;
13056         }
13057       else if (unformat (line_input, "group %U",
13058                          unformat_ip4_address, &remote4))
13059         {
13060           grp_set = remote_set = 1;
13061           ipv4_set = 1;
13062         }
13063       else if (unformat (line_input, "group %U %U",
13064                          unformat_ip6_address, &remote6,
13065                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13066         {
13067           grp_set = remote_set = 1;
13068           ipv6_set = 1;
13069         }
13070       else if (unformat (line_input, "group %U",
13071                          unformat_ip6_address, &remote6))
13072         {
13073           grp_set = remote_set = 1;
13074           ipv6_set = 1;
13075         }
13076       else
13077         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13078         ;
13079       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13080         ;
13081       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13082         ;
13083       else if (unformat (line_input, "vni %d", &vni))
13084         vni_set = 1;
13085       else if (unformat (line_input, "next-ip4"))
13086         protocol = 1;
13087       else if (unformat (line_input, "next-ip6"))
13088         protocol = 2;
13089       else if (unformat (line_input, "next-ethernet"))
13090         protocol = 3;
13091       else if (unformat (line_input, "next-nsh"))
13092         protocol = 4;
13093       else
13094         {
13095           errmsg ("parse error '%U'", format_unformat_error, line_input);
13096           return -99;
13097         }
13098     }
13099
13100   if (local_set == 0)
13101     {
13102       errmsg ("tunnel local address not specified");
13103       return -99;
13104     }
13105   if (remote_set == 0)
13106     {
13107       errmsg ("tunnel remote address not specified");
13108       return -99;
13109     }
13110   if (grp_set && mcast_sw_if_index == ~0)
13111     {
13112       errmsg ("tunnel nonexistent multicast device");
13113       return -99;
13114     }
13115   if (ipv4_set && ipv6_set)
13116     {
13117       errmsg ("both IPv4 and IPv6 addresses specified");
13118       return -99;
13119     }
13120
13121   if (vni_set == 0)
13122     {
13123       errmsg ("vni not specified");
13124       return -99;
13125     }
13126
13127   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13128
13129
13130   if (ipv6_set)
13131     {
13132       clib_memcpy (&mp->local, &local6, sizeof (local6));
13133       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13134     }
13135   else
13136     {
13137       clib_memcpy (&mp->local, &local4, sizeof (local4));
13138       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13139     }
13140
13141   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13142   mp->encap_vrf_id = ntohl (encap_vrf_id);
13143   mp->decap_vrf_id = ntohl (decap_vrf_id);
13144   mp->protocol = protocol;
13145   mp->vni = ntohl (vni);
13146   mp->is_add = is_add;
13147   mp->is_ipv6 = ipv6_set;
13148
13149   S (mp);
13150   W (ret);
13151   return ret;
13152 }
13153
13154 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13155   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13156 {
13157   vat_main_t *vam = &vat_main;
13158   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13159   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13160
13161   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13162          ntohl (mp->sw_if_index),
13163          format_ip46_address, &local, IP46_TYPE_ANY,
13164          format_ip46_address, &remote, IP46_TYPE_ANY,
13165          ntohl (mp->vni), mp->protocol,
13166          ntohl (mp->mcast_sw_if_index),
13167          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13168 }
13169
13170
13171 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13172   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13173 {
13174   vat_main_t *vam = &vat_main;
13175   vat_json_node_t *node = NULL;
13176   struct in_addr ip4;
13177   struct in6_addr ip6;
13178
13179   if (VAT_JSON_ARRAY != vam->json_tree.type)
13180     {
13181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13182       vat_json_init_array (&vam->json_tree);
13183     }
13184   node = vat_json_array_add (&vam->json_tree);
13185
13186   vat_json_init_object (node);
13187   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13188   if (mp->is_ipv6)
13189     {
13190       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13191       vat_json_object_add_ip6 (node, "local", ip6);
13192       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13193       vat_json_object_add_ip6 (node, "remote", ip6);
13194     }
13195   else
13196     {
13197       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13198       vat_json_object_add_ip4 (node, "local", ip4);
13199       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13200       vat_json_object_add_ip4 (node, "remote", ip4);
13201     }
13202   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13203   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13204   vat_json_object_add_uint (node, "mcast_sw_if_index",
13205                             ntohl (mp->mcast_sw_if_index));
13206   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13207   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13208   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13209 }
13210
13211 static int
13212 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13213 {
13214   unformat_input_t *i = vam->input;
13215   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13216   vl_api_control_ping_t *mp_ping;
13217   u32 sw_if_index;
13218   u8 sw_if_index_set = 0;
13219   int ret;
13220
13221   /* Parse args required to build the message */
13222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13223     {
13224       if (unformat (i, "sw_if_index %d", &sw_if_index))
13225         sw_if_index_set = 1;
13226       else
13227         break;
13228     }
13229
13230   if (sw_if_index_set == 0)
13231     {
13232       sw_if_index = ~0;
13233     }
13234
13235   if (!vam->json_output)
13236     {
13237       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13238              "sw_if_index", "local", "remote", "vni",
13239              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13240     }
13241
13242   /* Get list of vxlan-tunnel interfaces */
13243   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13244
13245   mp->sw_if_index = htonl (sw_if_index);
13246
13247   S (mp);
13248
13249   /* Use a control ping for synchronization */
13250   MPING (CONTROL_PING, mp_ping);
13251   S (mp_ping);
13252
13253   W (ret);
13254   return ret;
13255 }
13256
13257
13258 u8 *
13259 format_l2_fib_mac_address (u8 * s, va_list * args)
13260 {
13261   u8 *a = va_arg (*args, u8 *);
13262
13263   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13264                  a[2], a[3], a[4], a[5], a[6], a[7]);
13265 }
13266
13267 static void vl_api_l2_fib_table_details_t_handler
13268   (vl_api_l2_fib_table_details_t * mp)
13269 {
13270   vat_main_t *vam = &vat_main;
13271
13272   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13273          "       %d       %d     %d",
13274          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13275          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13276          mp->bvi_mac);
13277 }
13278
13279 static void vl_api_l2_fib_table_details_t_handler_json
13280   (vl_api_l2_fib_table_details_t * mp)
13281 {
13282   vat_main_t *vam = &vat_main;
13283   vat_json_node_t *node = NULL;
13284
13285   if (VAT_JSON_ARRAY != vam->json_tree.type)
13286     {
13287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13288       vat_json_init_array (&vam->json_tree);
13289     }
13290   node = vat_json_array_add (&vam->json_tree);
13291
13292   vat_json_init_object (node);
13293   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13294   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13295   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13296   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13297   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13298   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13299 }
13300
13301 static int
13302 api_l2_fib_table_dump (vat_main_t * vam)
13303 {
13304   unformat_input_t *i = vam->input;
13305   vl_api_l2_fib_table_dump_t *mp;
13306   vl_api_control_ping_t *mp_ping;
13307   u32 bd_id;
13308   u8 bd_id_set = 0;
13309   int ret;
13310
13311   /* Parse args required to build the message */
13312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13313     {
13314       if (unformat (i, "bd_id %d", &bd_id))
13315         bd_id_set = 1;
13316       else
13317         break;
13318     }
13319
13320   if (bd_id_set == 0)
13321     {
13322       errmsg ("missing bridge domain");
13323       return -99;
13324     }
13325
13326   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13327
13328   /* Get list of l2 fib entries */
13329   M (L2_FIB_TABLE_DUMP, mp);
13330
13331   mp->bd_id = ntohl (bd_id);
13332   S (mp);
13333
13334   /* Use a control ping for synchronization */
13335   MPING (CONTROL_PING, mp_ping);
13336   S (mp_ping);
13337
13338   W (ret);
13339   return ret;
13340 }
13341
13342
13343 static int
13344 api_interface_name_renumber (vat_main_t * vam)
13345 {
13346   unformat_input_t *line_input = vam->input;
13347   vl_api_interface_name_renumber_t *mp;
13348   u32 sw_if_index = ~0;
13349   u32 new_show_dev_instance = ~0;
13350   int ret;
13351
13352   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13355                     &sw_if_index))
13356         ;
13357       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13358         ;
13359       else if (unformat (line_input, "new_show_dev_instance %d",
13360                          &new_show_dev_instance))
13361         ;
13362       else
13363         break;
13364     }
13365
13366   if (sw_if_index == ~0)
13367     {
13368       errmsg ("missing interface name or sw_if_index");
13369       return -99;
13370     }
13371
13372   if (new_show_dev_instance == ~0)
13373     {
13374       errmsg ("missing new_show_dev_instance");
13375       return -99;
13376     }
13377
13378   M (INTERFACE_NAME_RENUMBER, mp);
13379
13380   mp->sw_if_index = ntohl (sw_if_index);
13381   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13382
13383   S (mp);
13384   W (ret);
13385   return ret;
13386 }
13387
13388 static int
13389 api_want_ip4_arp_events (vat_main_t * vam)
13390 {
13391   unformat_input_t *line_input = vam->input;
13392   vl_api_want_ip4_arp_events_t *mp;
13393   ip4_address_t address;
13394   int address_set = 0;
13395   u32 enable_disable = 1;
13396   int ret;
13397
13398   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13399     {
13400       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13401         address_set = 1;
13402       else if (unformat (line_input, "del"))
13403         enable_disable = 0;
13404       else
13405         break;
13406     }
13407
13408   if (address_set == 0)
13409     {
13410       errmsg ("missing addresses");
13411       return -99;
13412     }
13413
13414   M (WANT_IP4_ARP_EVENTS, mp);
13415   mp->enable_disable = enable_disable;
13416   mp->pid = htonl (getpid ());
13417   mp->address = address.as_u32;
13418
13419   S (mp);
13420   W (ret);
13421   return ret;
13422 }
13423
13424 static int
13425 api_want_ip6_nd_events (vat_main_t * vam)
13426 {
13427   unformat_input_t *line_input = vam->input;
13428   vl_api_want_ip6_nd_events_t *mp;
13429   ip6_address_t address;
13430   int address_set = 0;
13431   u32 enable_disable = 1;
13432   int ret;
13433
13434   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13435     {
13436       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13437         address_set = 1;
13438       else if (unformat (line_input, "del"))
13439         enable_disable = 0;
13440       else
13441         break;
13442     }
13443
13444   if (address_set == 0)
13445     {
13446       errmsg ("missing addresses");
13447       return -99;
13448     }
13449
13450   M (WANT_IP6_ND_EVENTS, mp);
13451   mp->enable_disable = enable_disable;
13452   mp->pid = htonl (getpid ());
13453   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13454
13455   S (mp);
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static int
13461 api_want_l2_macs_events (vat_main_t * vam)
13462 {
13463   unformat_input_t *line_input = vam->input;
13464   vl_api_want_l2_macs_events_t *mp;
13465   u8 enable_disable = 1;
13466   u32 scan_delay = 0;
13467   u32 max_macs_in_event = 0;
13468   u32 learn_limit = 0;
13469   int ret;
13470
13471   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (line_input, "learn-limit %d", &learn_limit))
13474         ;
13475       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13476         ;
13477       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13478         ;
13479       else if (unformat (line_input, "disable"))
13480         enable_disable = 0;
13481       else
13482         break;
13483     }
13484
13485   M (WANT_L2_MACS_EVENTS, mp);
13486   mp->enable_disable = enable_disable;
13487   mp->pid = htonl (getpid ());
13488   mp->learn_limit = htonl (learn_limit);
13489   mp->scan_delay = (u8) scan_delay;
13490   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13491   S (mp);
13492   W (ret);
13493   return ret;
13494 }
13495
13496 static int
13497 api_input_acl_set_interface (vat_main_t * vam)
13498 {
13499   unformat_input_t *i = vam->input;
13500   vl_api_input_acl_set_interface_t *mp;
13501   u32 sw_if_index;
13502   int sw_if_index_set;
13503   u32 ip4_table_index = ~0;
13504   u32 ip6_table_index = ~0;
13505   u32 l2_table_index = ~0;
13506   u8 is_add = 1;
13507   int ret;
13508
13509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13510     {
13511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13512         sw_if_index_set = 1;
13513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13514         sw_if_index_set = 1;
13515       else if (unformat (i, "del"))
13516         is_add = 0;
13517       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13518         ;
13519       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13520         ;
13521       else if (unformat (i, "l2-table %d", &l2_table_index))
13522         ;
13523       else
13524         {
13525           clib_warning ("parse error '%U'", format_unformat_error, i);
13526           return -99;
13527         }
13528     }
13529
13530   if (sw_if_index_set == 0)
13531     {
13532       errmsg ("missing interface name or sw_if_index");
13533       return -99;
13534     }
13535
13536   M (INPUT_ACL_SET_INTERFACE, mp);
13537
13538   mp->sw_if_index = ntohl (sw_if_index);
13539   mp->ip4_table_index = ntohl (ip4_table_index);
13540   mp->ip6_table_index = ntohl (ip6_table_index);
13541   mp->l2_table_index = ntohl (l2_table_index);
13542   mp->is_add = is_add;
13543
13544   S (mp);
13545   W (ret);
13546   return ret;
13547 }
13548
13549 static int
13550 api_ip_address_dump (vat_main_t * vam)
13551 {
13552   unformat_input_t *i = vam->input;
13553   vl_api_ip_address_dump_t *mp;
13554   vl_api_control_ping_t *mp_ping;
13555   u32 sw_if_index = ~0;
13556   u8 sw_if_index_set = 0;
13557   u8 ipv4_set = 0;
13558   u8 ipv6_set = 0;
13559   int ret;
13560
13561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13562     {
13563       if (unformat (i, "sw_if_index %d", &sw_if_index))
13564         sw_if_index_set = 1;
13565       else
13566         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13567         sw_if_index_set = 1;
13568       else if (unformat (i, "ipv4"))
13569         ipv4_set = 1;
13570       else if (unformat (i, "ipv6"))
13571         ipv6_set = 1;
13572       else
13573         break;
13574     }
13575
13576   if (ipv4_set && ipv6_set)
13577     {
13578       errmsg ("ipv4 and ipv6 flags cannot be both set");
13579       return -99;
13580     }
13581
13582   if ((!ipv4_set) && (!ipv6_set))
13583     {
13584       errmsg ("no ipv4 nor ipv6 flag set");
13585       return -99;
13586     }
13587
13588   if (sw_if_index_set == 0)
13589     {
13590       errmsg ("missing interface name or sw_if_index");
13591       return -99;
13592     }
13593
13594   vam->current_sw_if_index = sw_if_index;
13595   vam->is_ipv6 = ipv6_set;
13596
13597   M (IP_ADDRESS_DUMP, mp);
13598   mp->sw_if_index = ntohl (sw_if_index);
13599   mp->is_ipv6 = ipv6_set;
13600   S (mp);
13601
13602   /* Use a control ping for synchronization */
13603   MPING (CONTROL_PING, mp_ping);
13604   S (mp_ping);
13605
13606   W (ret);
13607   return ret;
13608 }
13609
13610 static int
13611 api_ip_dump (vat_main_t * vam)
13612 {
13613   vl_api_ip_dump_t *mp;
13614   vl_api_control_ping_t *mp_ping;
13615   unformat_input_t *in = vam->input;
13616   int ipv4_set = 0;
13617   int ipv6_set = 0;
13618   int is_ipv6;
13619   int i;
13620   int ret;
13621
13622   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13623     {
13624       if (unformat (in, "ipv4"))
13625         ipv4_set = 1;
13626       else if (unformat (in, "ipv6"))
13627         ipv6_set = 1;
13628       else
13629         break;
13630     }
13631
13632   if (ipv4_set && ipv6_set)
13633     {
13634       errmsg ("ipv4 and ipv6 flags cannot be both set");
13635       return -99;
13636     }
13637
13638   if ((!ipv4_set) && (!ipv6_set))
13639     {
13640       errmsg ("no ipv4 nor ipv6 flag set");
13641       return -99;
13642     }
13643
13644   is_ipv6 = ipv6_set;
13645   vam->is_ipv6 = is_ipv6;
13646
13647   /* free old data */
13648   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13649     {
13650       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13651     }
13652   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13653
13654   M (IP_DUMP, mp);
13655   mp->is_ipv6 = ipv6_set;
13656   S (mp);
13657
13658   /* Use a control ping for synchronization */
13659   MPING (CONTROL_PING, mp_ping);
13660   S (mp_ping);
13661
13662   W (ret);
13663   return ret;
13664 }
13665
13666 static int
13667 api_ipsec_spd_add_del (vat_main_t * vam)
13668 {
13669   unformat_input_t *i = vam->input;
13670   vl_api_ipsec_spd_add_del_t *mp;
13671   u32 spd_id = ~0;
13672   u8 is_add = 1;
13673   int ret;
13674
13675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13676     {
13677       if (unformat (i, "spd_id %d", &spd_id))
13678         ;
13679       else if (unformat (i, "del"))
13680         is_add = 0;
13681       else
13682         {
13683           clib_warning ("parse error '%U'", format_unformat_error, i);
13684           return -99;
13685         }
13686     }
13687   if (spd_id == ~0)
13688     {
13689       errmsg ("spd_id must be set");
13690       return -99;
13691     }
13692
13693   M (IPSEC_SPD_ADD_DEL, mp);
13694
13695   mp->spd_id = ntohl (spd_id);
13696   mp->is_add = is_add;
13697
13698   S (mp);
13699   W (ret);
13700   return ret;
13701 }
13702
13703 static int
13704 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13705 {
13706   unformat_input_t *i = vam->input;
13707   vl_api_ipsec_interface_add_del_spd_t *mp;
13708   u32 sw_if_index;
13709   u8 sw_if_index_set = 0;
13710   u32 spd_id = (u32) ~ 0;
13711   u8 is_add = 1;
13712   int ret;
13713
13714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13715     {
13716       if (unformat (i, "del"))
13717         is_add = 0;
13718       else if (unformat (i, "spd_id %d", &spd_id))
13719         ;
13720       else
13721         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13722         sw_if_index_set = 1;
13723       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13724         sw_if_index_set = 1;
13725       else
13726         {
13727           clib_warning ("parse error '%U'", format_unformat_error, i);
13728           return -99;
13729         }
13730
13731     }
13732
13733   if (spd_id == (u32) ~ 0)
13734     {
13735       errmsg ("spd_id must be set");
13736       return -99;
13737     }
13738
13739   if (sw_if_index_set == 0)
13740     {
13741       errmsg ("missing interface name or sw_if_index");
13742       return -99;
13743     }
13744
13745   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13746
13747   mp->spd_id = ntohl (spd_id);
13748   mp->sw_if_index = ntohl (sw_if_index);
13749   mp->is_add = is_add;
13750
13751   S (mp);
13752   W (ret);
13753   return ret;
13754 }
13755
13756 static int
13757 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13758 {
13759   unformat_input_t *i = vam->input;
13760   vl_api_ipsec_spd_add_del_entry_t *mp;
13761   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13762   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13763   i32 priority = 0;
13764   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13765   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13766   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13767   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13768   int ret;
13769
13770   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13771   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13772   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13773   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13774   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13775   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13776
13777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13778     {
13779       if (unformat (i, "del"))
13780         is_add = 0;
13781       if (unformat (i, "outbound"))
13782         is_outbound = 1;
13783       if (unformat (i, "inbound"))
13784         is_outbound = 0;
13785       else if (unformat (i, "spd_id %d", &spd_id))
13786         ;
13787       else if (unformat (i, "sa_id %d", &sa_id))
13788         ;
13789       else if (unformat (i, "priority %d", &priority))
13790         ;
13791       else if (unformat (i, "protocol %d", &protocol))
13792         ;
13793       else if (unformat (i, "lport_start %d", &lport_start))
13794         ;
13795       else if (unformat (i, "lport_stop %d", &lport_stop))
13796         ;
13797       else if (unformat (i, "rport_start %d", &rport_start))
13798         ;
13799       else if (unformat (i, "rport_stop %d", &rport_stop))
13800         ;
13801       else
13802         if (unformat
13803             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13804         {
13805           is_ipv6 = 0;
13806           is_ip_any = 0;
13807         }
13808       else
13809         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13810         {
13811           is_ipv6 = 0;
13812           is_ip_any = 0;
13813         }
13814       else
13815         if (unformat
13816             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13817         {
13818           is_ipv6 = 0;
13819           is_ip_any = 0;
13820         }
13821       else
13822         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13823         {
13824           is_ipv6 = 0;
13825           is_ip_any = 0;
13826         }
13827       else
13828         if (unformat
13829             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13830         {
13831           is_ipv6 = 1;
13832           is_ip_any = 0;
13833         }
13834       else
13835         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13836         {
13837           is_ipv6 = 1;
13838           is_ip_any = 0;
13839         }
13840       else
13841         if (unformat
13842             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13843         {
13844           is_ipv6 = 1;
13845           is_ip_any = 0;
13846         }
13847       else
13848         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13849         {
13850           is_ipv6 = 1;
13851           is_ip_any = 0;
13852         }
13853       else
13854         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13855         {
13856           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13857             {
13858               clib_warning ("unsupported action: 'resolve'");
13859               return -99;
13860             }
13861         }
13862       else
13863         {
13864           clib_warning ("parse error '%U'", format_unformat_error, i);
13865           return -99;
13866         }
13867
13868     }
13869
13870   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13871
13872   mp->spd_id = ntohl (spd_id);
13873   mp->priority = ntohl (priority);
13874   mp->is_outbound = is_outbound;
13875
13876   mp->is_ipv6 = is_ipv6;
13877   if (is_ipv6 || is_ip_any)
13878     {
13879       clib_memcpy (mp->remote_address_start, &raddr6_start,
13880                    sizeof (ip6_address_t));
13881       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13882                    sizeof (ip6_address_t));
13883       clib_memcpy (mp->local_address_start, &laddr6_start,
13884                    sizeof (ip6_address_t));
13885       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13886                    sizeof (ip6_address_t));
13887     }
13888   else
13889     {
13890       clib_memcpy (mp->remote_address_start, &raddr4_start,
13891                    sizeof (ip4_address_t));
13892       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13893                    sizeof (ip4_address_t));
13894       clib_memcpy (mp->local_address_start, &laddr4_start,
13895                    sizeof (ip4_address_t));
13896       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13897                    sizeof (ip4_address_t));
13898     }
13899   mp->protocol = (u8) protocol;
13900   mp->local_port_start = ntohs ((u16) lport_start);
13901   mp->local_port_stop = ntohs ((u16) lport_stop);
13902   mp->remote_port_start = ntohs ((u16) rport_start);
13903   mp->remote_port_stop = ntohs ((u16) rport_stop);
13904   mp->policy = (u8) policy;
13905   mp->sa_id = ntohl (sa_id);
13906   mp->is_add = is_add;
13907   mp->is_ip_any = is_ip_any;
13908   S (mp);
13909   W (ret);
13910   return ret;
13911 }
13912
13913 static int
13914 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13915 {
13916   unformat_input_t *i = vam->input;
13917   vl_api_ipsec_sad_add_del_entry_t *mp;
13918   u32 sad_id = 0, spi = 0;
13919   u8 *ck = 0, *ik = 0;
13920   u8 is_add = 1;
13921
13922   u8 protocol = IPSEC_PROTOCOL_AH;
13923   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13924   u32 crypto_alg = 0, integ_alg = 0;
13925   ip4_address_t tun_src4;
13926   ip4_address_t tun_dst4;
13927   ip6_address_t tun_src6;
13928   ip6_address_t tun_dst6;
13929   int ret;
13930
13931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13932     {
13933       if (unformat (i, "del"))
13934         is_add = 0;
13935       else if (unformat (i, "sad_id %d", &sad_id))
13936         ;
13937       else if (unformat (i, "spi %d", &spi))
13938         ;
13939       else if (unformat (i, "esp"))
13940         protocol = IPSEC_PROTOCOL_ESP;
13941       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13942         {
13943           is_tunnel = 1;
13944           is_tunnel_ipv6 = 0;
13945         }
13946       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13947         {
13948           is_tunnel = 1;
13949           is_tunnel_ipv6 = 0;
13950         }
13951       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13952         {
13953           is_tunnel = 1;
13954           is_tunnel_ipv6 = 1;
13955         }
13956       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13957         {
13958           is_tunnel = 1;
13959           is_tunnel_ipv6 = 1;
13960         }
13961       else
13962         if (unformat
13963             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13964         {
13965           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13966               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13967             {
13968               clib_warning ("unsupported crypto-alg: '%U'",
13969                             format_ipsec_crypto_alg, crypto_alg);
13970               return -99;
13971             }
13972         }
13973       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13974         ;
13975       else
13976         if (unformat
13977             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13978         {
13979           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13980               integ_alg >= IPSEC_INTEG_N_ALG)
13981             {
13982               clib_warning ("unsupported integ-alg: '%U'",
13983                             format_ipsec_integ_alg, integ_alg);
13984               return -99;
13985             }
13986         }
13987       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13988         ;
13989       else
13990         {
13991           clib_warning ("parse error '%U'", format_unformat_error, i);
13992           return -99;
13993         }
13994
13995     }
13996
13997   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13998
13999   mp->sad_id = ntohl (sad_id);
14000   mp->is_add = is_add;
14001   mp->protocol = protocol;
14002   mp->spi = ntohl (spi);
14003   mp->is_tunnel = is_tunnel;
14004   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14005   mp->crypto_algorithm = crypto_alg;
14006   mp->integrity_algorithm = integ_alg;
14007   mp->crypto_key_length = vec_len (ck);
14008   mp->integrity_key_length = vec_len (ik);
14009
14010   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14011     mp->crypto_key_length = sizeof (mp->crypto_key);
14012
14013   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14014     mp->integrity_key_length = sizeof (mp->integrity_key);
14015
14016   if (ck)
14017     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14018   if (ik)
14019     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14020
14021   if (is_tunnel)
14022     {
14023       if (is_tunnel_ipv6)
14024         {
14025           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14026                        sizeof (ip6_address_t));
14027           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14028                        sizeof (ip6_address_t));
14029         }
14030       else
14031         {
14032           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14033                        sizeof (ip4_address_t));
14034           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14035                        sizeof (ip4_address_t));
14036         }
14037     }
14038
14039   S (mp);
14040   W (ret);
14041   return ret;
14042 }
14043
14044 static int
14045 api_ipsec_sa_set_key (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_ipsec_sa_set_key_t *mp;
14049   u32 sa_id;
14050   u8 *ck = 0, *ik = 0;
14051   int ret;
14052
14053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14054     {
14055       if (unformat (i, "sa_id %d", &sa_id))
14056         ;
14057       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14058         ;
14059       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14060         ;
14061       else
14062         {
14063           clib_warning ("parse error '%U'", format_unformat_error, i);
14064           return -99;
14065         }
14066     }
14067
14068   M (IPSEC_SA_SET_KEY, mp);
14069
14070   mp->sa_id = ntohl (sa_id);
14071   mp->crypto_key_length = vec_len (ck);
14072   mp->integrity_key_length = vec_len (ik);
14073
14074   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14075     mp->crypto_key_length = sizeof (mp->crypto_key);
14076
14077   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14078     mp->integrity_key_length = sizeof (mp->integrity_key);
14079
14080   if (ck)
14081     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14082   if (ik)
14083     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14084
14085   S (mp);
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_ipsec_tunnel_if_add_del_t *mp;
14095   u32 local_spi = 0, remote_spi = 0;
14096   u32 crypto_alg = 0, integ_alg = 0;
14097   u8 *lck = NULL, *rck = NULL;
14098   u8 *lik = NULL, *rik = NULL;
14099   ip4_address_t local_ip = { {0} };
14100   ip4_address_t remote_ip = { {0} };
14101   u8 is_add = 1;
14102   u8 esn = 0;
14103   u8 anti_replay = 0;
14104   int ret;
14105
14106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14107     {
14108       if (unformat (i, "del"))
14109         is_add = 0;
14110       else if (unformat (i, "esn"))
14111         esn = 1;
14112       else if (unformat (i, "anti_replay"))
14113         anti_replay = 1;
14114       else if (unformat (i, "local_spi %d", &local_spi))
14115         ;
14116       else if (unformat (i, "remote_spi %d", &remote_spi))
14117         ;
14118       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14119         ;
14120       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14121         ;
14122       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14123         ;
14124       else
14125         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14126         ;
14127       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14128         ;
14129       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14130         ;
14131       else
14132         if (unformat
14133             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14134         {
14135           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14136               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14137             {
14138               errmsg ("unsupported crypto-alg: '%U'\n",
14139                       format_ipsec_crypto_alg, crypto_alg);
14140               return -99;
14141             }
14142         }
14143       else
14144         if (unformat
14145             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14146         {
14147           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14148               integ_alg >= IPSEC_INTEG_N_ALG)
14149             {
14150               errmsg ("unsupported integ-alg: '%U'\n",
14151                       format_ipsec_integ_alg, integ_alg);
14152               return -99;
14153             }
14154         }
14155       else
14156         {
14157           errmsg ("parse error '%U'\n", format_unformat_error, i);
14158           return -99;
14159         }
14160     }
14161
14162   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14163
14164   mp->is_add = is_add;
14165   mp->esn = esn;
14166   mp->anti_replay = anti_replay;
14167
14168   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14169   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14170
14171   mp->local_spi = htonl (local_spi);
14172   mp->remote_spi = htonl (remote_spi);
14173   mp->crypto_alg = (u8) crypto_alg;
14174
14175   mp->local_crypto_key_len = 0;
14176   if (lck)
14177     {
14178       mp->local_crypto_key_len = vec_len (lck);
14179       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14180         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14181       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14182     }
14183
14184   mp->remote_crypto_key_len = 0;
14185   if (rck)
14186     {
14187       mp->remote_crypto_key_len = vec_len (rck);
14188       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14189         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14190       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14191     }
14192
14193   mp->integ_alg = (u8) integ_alg;
14194
14195   mp->local_integ_key_len = 0;
14196   if (lik)
14197     {
14198       mp->local_integ_key_len = vec_len (lik);
14199       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14200         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14201       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14202     }
14203
14204   mp->remote_integ_key_len = 0;
14205   if (rik)
14206     {
14207       mp->remote_integ_key_len = vec_len (rik);
14208       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14209         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14210       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14211     }
14212
14213   S (mp);
14214   W (ret);
14215   return ret;
14216 }
14217
14218 static void
14219 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14220 {
14221   vat_main_t *vam = &vat_main;
14222
14223   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14224          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14225          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14226          "tunnel_src_addr %U tunnel_dst_addr %U "
14227          "salt %u seq_outbound %lu last_seq_inbound %lu "
14228          "replay_window %lu total_data_size %lu\n",
14229          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14230          mp->protocol,
14231          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14232          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14233          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14234          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14235          mp->tunnel_src_addr,
14236          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14237          mp->tunnel_dst_addr,
14238          ntohl (mp->salt),
14239          clib_net_to_host_u64 (mp->seq_outbound),
14240          clib_net_to_host_u64 (mp->last_seq_inbound),
14241          clib_net_to_host_u64 (mp->replay_window),
14242          clib_net_to_host_u64 (mp->total_data_size));
14243 }
14244
14245 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14246 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14247
14248 static void vl_api_ipsec_sa_details_t_handler_json
14249   (vl_api_ipsec_sa_details_t * mp)
14250 {
14251   vat_main_t *vam = &vat_main;
14252   vat_json_node_t *node = NULL;
14253   struct in_addr src_ip4, dst_ip4;
14254   struct in6_addr src_ip6, dst_ip6;
14255
14256   if (VAT_JSON_ARRAY != vam->json_tree.type)
14257     {
14258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14259       vat_json_init_array (&vam->json_tree);
14260     }
14261   node = vat_json_array_add (&vam->json_tree);
14262
14263   vat_json_init_object (node);
14264   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14265   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14266   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14267   vat_json_object_add_uint (node, "proto", mp->protocol);
14268   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14269   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14270   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14271   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14272   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14273   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14274   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14275                              mp->crypto_key_len);
14276   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14277                              mp->integ_key_len);
14278   if (mp->is_tunnel_ip6)
14279     {
14280       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14281       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14282       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14283       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14284     }
14285   else
14286     {
14287       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14288       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14289       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14290       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14291     }
14292   vat_json_object_add_uint (node, "replay_window",
14293                             clib_net_to_host_u64 (mp->replay_window));
14294   vat_json_object_add_uint (node, "total_data_size",
14295                             clib_net_to_host_u64 (mp->total_data_size));
14296
14297 }
14298
14299 static int
14300 api_ipsec_sa_dump (vat_main_t * vam)
14301 {
14302   unformat_input_t *i = vam->input;
14303   vl_api_ipsec_sa_dump_t *mp;
14304   vl_api_control_ping_t *mp_ping;
14305   u32 sa_id = ~0;
14306   int ret;
14307
14308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14309     {
14310       if (unformat (i, "sa_id %d", &sa_id))
14311         ;
14312       else
14313         {
14314           clib_warning ("parse error '%U'", format_unformat_error, i);
14315           return -99;
14316         }
14317     }
14318
14319   M (IPSEC_SA_DUMP, mp);
14320
14321   mp->sa_id = ntohl (sa_id);
14322
14323   S (mp);
14324
14325   /* Use a control ping for synchronization */
14326   M (CONTROL_PING, mp_ping);
14327   S (mp_ping);
14328
14329   W (ret);
14330   return ret;
14331 }
14332
14333 static int
14334 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14335 {
14336   unformat_input_t *i = vam->input;
14337   vl_api_ipsec_tunnel_if_set_key_t *mp;
14338   u32 sw_if_index = ~0;
14339   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14340   u8 *key = 0;
14341   u32 alg = ~0;
14342   int ret;
14343
14344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14345     {
14346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14347         ;
14348       else
14349         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14350         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14351       else
14352         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14353         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14354       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14355         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14356       else
14357         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14358         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14359       else if (unformat (i, "%U", unformat_hex_string, &key))
14360         ;
14361       else
14362         {
14363           clib_warning ("parse error '%U'", format_unformat_error, i);
14364           return -99;
14365         }
14366     }
14367
14368   if (sw_if_index == ~0)
14369     {
14370       errmsg ("interface must be specified");
14371       return -99;
14372     }
14373
14374   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14375     {
14376       errmsg ("key type must be specified");
14377       return -99;
14378     }
14379
14380   if (alg == ~0)
14381     {
14382       errmsg ("algorithm must be specified");
14383       return -99;
14384     }
14385
14386   if (vec_len (key) == 0)
14387     {
14388       errmsg ("key must be specified");
14389       return -99;
14390     }
14391
14392   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14393
14394   mp->sw_if_index = htonl (sw_if_index);
14395   mp->alg = alg;
14396   mp->key_type = key_type;
14397   mp->key_len = vec_len (key);
14398   clib_memcpy (mp->key, key, vec_len (key));
14399
14400   S (mp);
14401   W (ret);
14402
14403   return ret;
14404 }
14405
14406 static int
14407 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14408 {
14409   unformat_input_t *i = vam->input;
14410   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14411   u32 sw_if_index = ~0;
14412   u32 sa_id = ~0;
14413   u8 is_outbound = (u8) ~ 0;
14414   int ret;
14415
14416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14417     {
14418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14419         ;
14420       else if (unformat (i, "sa_id %d", &sa_id))
14421         ;
14422       else if (unformat (i, "outbound"))
14423         is_outbound = 1;
14424       else if (unformat (i, "inbound"))
14425         is_outbound = 0;
14426       else
14427         {
14428           clib_warning ("parse error '%U'", format_unformat_error, i);
14429           return -99;
14430         }
14431     }
14432
14433   if (sw_if_index == ~0)
14434     {
14435       errmsg ("interface must be specified");
14436       return -99;
14437     }
14438
14439   if (sa_id == ~0)
14440     {
14441       errmsg ("SA ID must be specified");
14442       return -99;
14443     }
14444
14445   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14446
14447   mp->sw_if_index = htonl (sw_if_index);
14448   mp->sa_id = htonl (sa_id);
14449   mp->is_outbound = is_outbound;
14450
14451   S (mp);
14452   W (ret);
14453
14454   return ret;
14455 }
14456
14457 static int
14458 api_ikev2_profile_add_del (vat_main_t * vam)
14459 {
14460   unformat_input_t *i = vam->input;
14461   vl_api_ikev2_profile_add_del_t *mp;
14462   u8 is_add = 1;
14463   u8 *name = 0;
14464   int ret;
14465
14466   const char *valid_chars = "a-zA-Z0-9_";
14467
14468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14469     {
14470       if (unformat (i, "del"))
14471         is_add = 0;
14472       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14473         vec_add1 (name, 0);
14474       else
14475         {
14476           errmsg ("parse error '%U'", format_unformat_error, i);
14477           return -99;
14478         }
14479     }
14480
14481   if (!vec_len (name))
14482     {
14483       errmsg ("profile name must be specified");
14484       return -99;
14485     }
14486
14487   if (vec_len (name) > 64)
14488     {
14489       errmsg ("profile name too long");
14490       return -99;
14491     }
14492
14493   M (IKEV2_PROFILE_ADD_DEL, mp);
14494
14495   clib_memcpy (mp->name, name, vec_len (name));
14496   mp->is_add = is_add;
14497   vec_free (name);
14498
14499   S (mp);
14500   W (ret);
14501   return ret;
14502 }
14503
14504 static int
14505 api_ikev2_profile_set_auth (vat_main_t * vam)
14506 {
14507   unformat_input_t *i = vam->input;
14508   vl_api_ikev2_profile_set_auth_t *mp;
14509   u8 *name = 0;
14510   u8 *data = 0;
14511   u32 auth_method = 0;
14512   u8 is_hex = 0;
14513   int ret;
14514
14515   const char *valid_chars = "a-zA-Z0-9_";
14516
14517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14518     {
14519       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14520         vec_add1 (name, 0);
14521       else if (unformat (i, "auth_method %U",
14522                          unformat_ikev2_auth_method, &auth_method))
14523         ;
14524       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14525         is_hex = 1;
14526       else if (unformat (i, "auth_data %v", &data))
14527         ;
14528       else
14529         {
14530           errmsg ("parse error '%U'", format_unformat_error, i);
14531           return -99;
14532         }
14533     }
14534
14535   if (!vec_len (name))
14536     {
14537       errmsg ("profile name must be specified");
14538       return -99;
14539     }
14540
14541   if (vec_len (name) > 64)
14542     {
14543       errmsg ("profile name too long");
14544       return -99;
14545     }
14546
14547   if (!vec_len (data))
14548     {
14549       errmsg ("auth_data must be specified");
14550       return -99;
14551     }
14552
14553   if (!auth_method)
14554     {
14555       errmsg ("auth_method must be specified");
14556       return -99;
14557     }
14558
14559   M (IKEV2_PROFILE_SET_AUTH, mp);
14560
14561   mp->is_hex = is_hex;
14562   mp->auth_method = (u8) auth_method;
14563   mp->data_len = vec_len (data);
14564   clib_memcpy (mp->name, name, vec_len (name));
14565   clib_memcpy (mp->data, data, vec_len (data));
14566   vec_free (name);
14567   vec_free (data);
14568
14569   S (mp);
14570   W (ret);
14571   return ret;
14572 }
14573
14574 static int
14575 api_ikev2_profile_set_id (vat_main_t * vam)
14576 {
14577   unformat_input_t *i = vam->input;
14578   vl_api_ikev2_profile_set_id_t *mp;
14579   u8 *name = 0;
14580   u8 *data = 0;
14581   u8 is_local = 0;
14582   u32 id_type = 0;
14583   ip4_address_t ip4;
14584   int ret;
14585
14586   const char *valid_chars = "a-zA-Z0-9_";
14587
14588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14591         vec_add1 (name, 0);
14592       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14593         ;
14594       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14595         {
14596           data = vec_new (u8, 4);
14597           clib_memcpy (data, ip4.as_u8, 4);
14598         }
14599       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14600         ;
14601       else if (unformat (i, "id_data %v", &data))
14602         ;
14603       else if (unformat (i, "local"))
14604         is_local = 1;
14605       else if (unformat (i, "remote"))
14606         is_local = 0;
14607       else
14608         {
14609           errmsg ("parse error '%U'", format_unformat_error, i);
14610           return -99;
14611         }
14612     }
14613
14614   if (!vec_len (name))
14615     {
14616       errmsg ("profile name must be specified");
14617       return -99;
14618     }
14619
14620   if (vec_len (name) > 64)
14621     {
14622       errmsg ("profile name too long");
14623       return -99;
14624     }
14625
14626   if (!vec_len (data))
14627     {
14628       errmsg ("id_data must be specified");
14629       return -99;
14630     }
14631
14632   if (!id_type)
14633     {
14634       errmsg ("id_type must be specified");
14635       return -99;
14636     }
14637
14638   M (IKEV2_PROFILE_SET_ID, mp);
14639
14640   mp->is_local = is_local;
14641   mp->id_type = (u8) id_type;
14642   mp->data_len = vec_len (data);
14643   clib_memcpy (mp->name, name, vec_len (name));
14644   clib_memcpy (mp->data, data, vec_len (data));
14645   vec_free (name);
14646   vec_free (data);
14647
14648   S (mp);
14649   W (ret);
14650   return ret;
14651 }
14652
14653 static int
14654 api_ikev2_profile_set_ts (vat_main_t * vam)
14655 {
14656   unformat_input_t *i = vam->input;
14657   vl_api_ikev2_profile_set_ts_t *mp;
14658   u8 *name = 0;
14659   u8 is_local = 0;
14660   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14661   ip4_address_t start_addr, end_addr;
14662
14663   const char *valid_chars = "a-zA-Z0-9_";
14664   int ret;
14665
14666   start_addr.as_u32 = 0;
14667   end_addr.as_u32 = (u32) ~ 0;
14668
14669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14670     {
14671       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14672         vec_add1 (name, 0);
14673       else if (unformat (i, "protocol %d", &proto))
14674         ;
14675       else if (unformat (i, "start_port %d", &start_port))
14676         ;
14677       else if (unformat (i, "end_port %d", &end_port))
14678         ;
14679       else
14680         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14681         ;
14682       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14683         ;
14684       else if (unformat (i, "local"))
14685         is_local = 1;
14686       else if (unformat (i, "remote"))
14687         is_local = 0;
14688       else
14689         {
14690           errmsg ("parse error '%U'", format_unformat_error, i);
14691           return -99;
14692         }
14693     }
14694
14695   if (!vec_len (name))
14696     {
14697       errmsg ("profile name must be specified");
14698       return -99;
14699     }
14700
14701   if (vec_len (name) > 64)
14702     {
14703       errmsg ("profile name too long");
14704       return -99;
14705     }
14706
14707   M (IKEV2_PROFILE_SET_TS, mp);
14708
14709   mp->is_local = is_local;
14710   mp->proto = (u8) proto;
14711   mp->start_port = (u16) start_port;
14712   mp->end_port = (u16) end_port;
14713   mp->start_addr = start_addr.as_u32;
14714   mp->end_addr = end_addr.as_u32;
14715   clib_memcpy (mp->name, name, vec_len (name));
14716   vec_free (name);
14717
14718   S (mp);
14719   W (ret);
14720   return ret;
14721 }
14722
14723 static int
14724 api_ikev2_set_local_key (vat_main_t * vam)
14725 {
14726   unformat_input_t *i = vam->input;
14727   vl_api_ikev2_set_local_key_t *mp;
14728   u8 *file = 0;
14729   int ret;
14730
14731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (i, "file %v", &file))
14734         vec_add1 (file, 0);
14735       else
14736         {
14737           errmsg ("parse error '%U'", format_unformat_error, i);
14738           return -99;
14739         }
14740     }
14741
14742   if (!vec_len (file))
14743     {
14744       errmsg ("RSA key file must be specified");
14745       return -99;
14746     }
14747
14748   if (vec_len (file) > 256)
14749     {
14750       errmsg ("file name too long");
14751       return -99;
14752     }
14753
14754   M (IKEV2_SET_LOCAL_KEY, mp);
14755
14756   clib_memcpy (mp->key_file, file, vec_len (file));
14757   vec_free (file);
14758
14759   S (mp);
14760   W (ret);
14761   return ret;
14762 }
14763
14764 static int
14765 api_ikev2_set_responder (vat_main_t * vam)
14766 {
14767   unformat_input_t *i = vam->input;
14768   vl_api_ikev2_set_responder_t *mp;
14769   int ret;
14770   u8 *name = 0;
14771   u32 sw_if_index = ~0;
14772   ip4_address_t address;
14773
14774   const char *valid_chars = "a-zA-Z0-9_";
14775
14776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14777     {
14778       if (unformat
14779           (i, "%U interface %d address %U", unformat_token, valid_chars,
14780            &name, &sw_if_index, unformat_ip4_address, &address))
14781         vec_add1 (name, 0);
14782       else
14783         {
14784           errmsg ("parse error '%U'", format_unformat_error, i);
14785           return -99;
14786         }
14787     }
14788
14789   if (!vec_len (name))
14790     {
14791       errmsg ("profile name must be specified");
14792       return -99;
14793     }
14794
14795   if (vec_len (name) > 64)
14796     {
14797       errmsg ("profile name too long");
14798       return -99;
14799     }
14800
14801   M (IKEV2_SET_RESPONDER, mp);
14802
14803   clib_memcpy (mp->name, name, vec_len (name));
14804   vec_free (name);
14805
14806   mp->sw_if_index = sw_if_index;
14807   clib_memcpy (mp->address, &address, sizeof (address));
14808
14809   S (mp);
14810   W (ret);
14811   return ret;
14812 }
14813
14814 static int
14815 api_ikev2_set_ike_transforms (vat_main_t * vam)
14816 {
14817   unformat_input_t *i = vam->input;
14818   vl_api_ikev2_set_ike_transforms_t *mp;
14819   int ret;
14820   u8 *name = 0;
14821   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14822
14823   const char *valid_chars = "a-zA-Z0-9_";
14824
14825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14826     {
14827       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14828                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14829         vec_add1 (name, 0);
14830       else
14831         {
14832           errmsg ("parse error '%U'", format_unformat_error, i);
14833           return -99;
14834         }
14835     }
14836
14837   if (!vec_len (name))
14838     {
14839       errmsg ("profile name must be specified");
14840       return -99;
14841     }
14842
14843   if (vec_len (name) > 64)
14844     {
14845       errmsg ("profile name too long");
14846       return -99;
14847     }
14848
14849   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14850
14851   clib_memcpy (mp->name, name, vec_len (name));
14852   vec_free (name);
14853   mp->crypto_alg = crypto_alg;
14854   mp->crypto_key_size = crypto_key_size;
14855   mp->integ_alg = integ_alg;
14856   mp->dh_group = dh_group;
14857
14858   S (mp);
14859   W (ret);
14860   return ret;
14861 }
14862
14863
14864 static int
14865 api_ikev2_set_esp_transforms (vat_main_t * vam)
14866 {
14867   unformat_input_t *i = vam->input;
14868   vl_api_ikev2_set_esp_transforms_t *mp;
14869   int ret;
14870   u8 *name = 0;
14871   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14872
14873   const char *valid_chars = "a-zA-Z0-9_";
14874
14875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14876     {
14877       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14878                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14879         vec_add1 (name, 0);
14880       else
14881         {
14882           errmsg ("parse error '%U'", format_unformat_error, i);
14883           return -99;
14884         }
14885     }
14886
14887   if (!vec_len (name))
14888     {
14889       errmsg ("profile name must be specified");
14890       return -99;
14891     }
14892
14893   if (vec_len (name) > 64)
14894     {
14895       errmsg ("profile name too long");
14896       return -99;
14897     }
14898
14899   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14900
14901   clib_memcpy (mp->name, name, vec_len (name));
14902   vec_free (name);
14903   mp->crypto_alg = crypto_alg;
14904   mp->crypto_key_size = crypto_key_size;
14905   mp->integ_alg = integ_alg;
14906   mp->dh_group = dh_group;
14907
14908   S (mp);
14909   W (ret);
14910   return ret;
14911 }
14912
14913 static int
14914 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14915 {
14916   unformat_input_t *i = vam->input;
14917   vl_api_ikev2_set_sa_lifetime_t *mp;
14918   int ret;
14919   u8 *name = 0;
14920   u64 lifetime, lifetime_maxdata;
14921   u32 lifetime_jitter, handover;
14922
14923   const char *valid_chars = "a-zA-Z0-9_";
14924
14925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14926     {
14927       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14928                     &lifetime, &lifetime_jitter, &handover,
14929                     &lifetime_maxdata))
14930         vec_add1 (name, 0);
14931       else
14932         {
14933           errmsg ("parse error '%U'", format_unformat_error, i);
14934           return -99;
14935         }
14936     }
14937
14938   if (!vec_len (name))
14939     {
14940       errmsg ("profile name must be specified");
14941       return -99;
14942     }
14943
14944   if (vec_len (name) > 64)
14945     {
14946       errmsg ("profile name too long");
14947       return -99;
14948     }
14949
14950   M (IKEV2_SET_SA_LIFETIME, mp);
14951
14952   clib_memcpy (mp->name, name, vec_len (name));
14953   vec_free (name);
14954   mp->lifetime = lifetime;
14955   mp->lifetime_jitter = lifetime_jitter;
14956   mp->handover = handover;
14957   mp->lifetime_maxdata = lifetime_maxdata;
14958
14959   S (mp);
14960   W (ret);
14961   return ret;
14962 }
14963
14964 static int
14965 api_ikev2_initiate_sa_init (vat_main_t * vam)
14966 {
14967   unformat_input_t *i = vam->input;
14968   vl_api_ikev2_initiate_sa_init_t *mp;
14969   int ret;
14970   u8 *name = 0;
14971
14972   const char *valid_chars = "a-zA-Z0-9_";
14973
14974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14977         vec_add1 (name, 0);
14978       else
14979         {
14980           errmsg ("parse error '%U'", format_unformat_error, i);
14981           return -99;
14982         }
14983     }
14984
14985   if (!vec_len (name))
14986     {
14987       errmsg ("profile name must be specified");
14988       return -99;
14989     }
14990
14991   if (vec_len (name) > 64)
14992     {
14993       errmsg ("profile name too long");
14994       return -99;
14995     }
14996
14997   M (IKEV2_INITIATE_SA_INIT, mp);
14998
14999   clib_memcpy (mp->name, name, vec_len (name));
15000   vec_free (name);
15001
15002   S (mp);
15003   W (ret);
15004   return ret;
15005 }
15006
15007 static int
15008 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15009 {
15010   unformat_input_t *i = vam->input;
15011   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15012   int ret;
15013   u64 ispi;
15014
15015
15016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15017     {
15018       if (unformat (i, "%lx", &ispi))
15019         ;
15020       else
15021         {
15022           errmsg ("parse error '%U'", format_unformat_error, i);
15023           return -99;
15024         }
15025     }
15026
15027   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15028
15029   mp->ispi = ispi;
15030
15031   S (mp);
15032   W (ret);
15033   return ret;
15034 }
15035
15036 static int
15037 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15038 {
15039   unformat_input_t *i = vam->input;
15040   vl_api_ikev2_initiate_del_child_sa_t *mp;
15041   int ret;
15042   u32 ispi;
15043
15044
15045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15046     {
15047       if (unformat (i, "%x", &ispi))
15048         ;
15049       else
15050         {
15051           errmsg ("parse error '%U'", format_unformat_error, i);
15052           return -99;
15053         }
15054     }
15055
15056   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15057
15058   mp->ispi = ispi;
15059
15060   S (mp);
15061   W (ret);
15062   return ret;
15063 }
15064
15065 static int
15066 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15067 {
15068   unformat_input_t *i = vam->input;
15069   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15070   int ret;
15071   u32 ispi;
15072
15073
15074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15075     {
15076       if (unformat (i, "%x", &ispi))
15077         ;
15078       else
15079         {
15080           errmsg ("parse error '%U'", format_unformat_error, i);
15081           return -99;
15082         }
15083     }
15084
15085   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15086
15087   mp->ispi = ispi;
15088
15089   S (mp);
15090   W (ret);
15091   return ret;
15092 }
15093
15094 /*
15095  * MAP
15096  */
15097 static int
15098 api_map_add_domain (vat_main_t * vam)
15099 {
15100   unformat_input_t *i = vam->input;
15101   vl_api_map_add_domain_t *mp;
15102
15103   ip4_address_t ip4_prefix;
15104   ip6_address_t ip6_prefix;
15105   ip6_address_t ip6_src;
15106   u32 num_m_args = 0;
15107   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15108     0, psid_length = 0;
15109   u8 is_translation = 0;
15110   u32 mtu = 0;
15111   u32 ip6_src_len = 128;
15112   int ret;
15113
15114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15115     {
15116       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15117                     &ip4_prefix, &ip4_prefix_len))
15118         num_m_args++;
15119       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15120                          &ip6_prefix, &ip6_prefix_len))
15121         num_m_args++;
15122       else
15123         if (unformat
15124             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15125              &ip6_src_len))
15126         num_m_args++;
15127       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15128         num_m_args++;
15129       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15130         num_m_args++;
15131       else if (unformat (i, "psid-offset %d", &psid_offset))
15132         num_m_args++;
15133       else if (unformat (i, "psid-len %d", &psid_length))
15134         num_m_args++;
15135       else if (unformat (i, "mtu %d", &mtu))
15136         num_m_args++;
15137       else if (unformat (i, "map-t"))
15138         is_translation = 1;
15139       else
15140         {
15141           clib_warning ("parse error '%U'", format_unformat_error, i);
15142           return -99;
15143         }
15144     }
15145
15146   if (num_m_args < 3)
15147     {
15148       errmsg ("mandatory argument(s) missing");
15149       return -99;
15150     }
15151
15152   /* Construct the API message */
15153   M (MAP_ADD_DOMAIN, mp);
15154
15155   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15156   mp->ip4_prefix_len = ip4_prefix_len;
15157
15158   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15159   mp->ip6_prefix_len = ip6_prefix_len;
15160
15161   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15162   mp->ip6_src_prefix_len = ip6_src_len;
15163
15164   mp->ea_bits_len = ea_bits_len;
15165   mp->psid_offset = psid_offset;
15166   mp->psid_length = psid_length;
15167   mp->is_translation = is_translation;
15168   mp->mtu = htons (mtu);
15169
15170   /* send it... */
15171   S (mp);
15172
15173   /* Wait for a reply, return good/bad news  */
15174   W (ret);
15175   return ret;
15176 }
15177
15178 static int
15179 api_map_del_domain (vat_main_t * vam)
15180 {
15181   unformat_input_t *i = vam->input;
15182   vl_api_map_del_domain_t *mp;
15183
15184   u32 num_m_args = 0;
15185   u32 index;
15186   int ret;
15187
15188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15189     {
15190       if (unformat (i, "index %d", &index))
15191         num_m_args++;
15192       else
15193         {
15194           clib_warning ("parse error '%U'", format_unformat_error, i);
15195           return -99;
15196         }
15197     }
15198
15199   if (num_m_args != 1)
15200     {
15201       errmsg ("mandatory argument(s) missing");
15202       return -99;
15203     }
15204
15205   /* Construct the API message */
15206   M (MAP_DEL_DOMAIN, mp);
15207
15208   mp->index = ntohl (index);
15209
15210   /* send it... */
15211   S (mp);
15212
15213   /* Wait for a reply, return good/bad news  */
15214   W (ret);
15215   return ret;
15216 }
15217
15218 static int
15219 api_map_add_del_rule (vat_main_t * vam)
15220 {
15221   unformat_input_t *i = vam->input;
15222   vl_api_map_add_del_rule_t *mp;
15223   u8 is_add = 1;
15224   ip6_address_t ip6_dst;
15225   u32 num_m_args = 0, index, psid = 0;
15226   int ret;
15227
15228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (i, "index %d", &index))
15231         num_m_args++;
15232       else if (unformat (i, "psid %d", &psid))
15233         num_m_args++;
15234       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15235         num_m_args++;
15236       else if (unformat (i, "del"))
15237         {
15238           is_add = 0;
15239         }
15240       else
15241         {
15242           clib_warning ("parse error '%U'", format_unformat_error, i);
15243           return -99;
15244         }
15245     }
15246
15247   /* Construct the API message */
15248   M (MAP_ADD_DEL_RULE, mp);
15249
15250   mp->index = ntohl (index);
15251   mp->is_add = is_add;
15252   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15253   mp->psid = ntohs (psid);
15254
15255   /* send it... */
15256   S (mp);
15257
15258   /* Wait for a reply, return good/bad news  */
15259   W (ret);
15260   return ret;
15261 }
15262
15263 static int
15264 api_map_domain_dump (vat_main_t * vam)
15265 {
15266   vl_api_map_domain_dump_t *mp;
15267   vl_api_control_ping_t *mp_ping;
15268   int ret;
15269
15270   /* Construct the API message */
15271   M (MAP_DOMAIN_DUMP, mp);
15272
15273   /* send it... */
15274   S (mp);
15275
15276   /* Use a control ping for synchronization */
15277   MPING (CONTROL_PING, mp_ping);
15278   S (mp_ping);
15279
15280   W (ret);
15281   return ret;
15282 }
15283
15284 static int
15285 api_map_rule_dump (vat_main_t * vam)
15286 {
15287   unformat_input_t *i = vam->input;
15288   vl_api_map_rule_dump_t *mp;
15289   vl_api_control_ping_t *mp_ping;
15290   u32 domain_index = ~0;
15291   int ret;
15292
15293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15294     {
15295       if (unformat (i, "index %u", &domain_index))
15296         ;
15297       else
15298         break;
15299     }
15300
15301   if (domain_index == ~0)
15302     {
15303       clib_warning ("parse error: domain index expected");
15304       return -99;
15305     }
15306
15307   /* Construct the API message */
15308   M (MAP_RULE_DUMP, mp);
15309
15310   mp->domain_index = htonl (domain_index);
15311
15312   /* send it... */
15313   S (mp);
15314
15315   /* Use a control ping for synchronization */
15316   MPING (CONTROL_PING, mp_ping);
15317   S (mp_ping);
15318
15319   W (ret);
15320   return ret;
15321 }
15322
15323 static void vl_api_map_add_domain_reply_t_handler
15324   (vl_api_map_add_domain_reply_t * mp)
15325 {
15326   vat_main_t *vam = &vat_main;
15327   i32 retval = ntohl (mp->retval);
15328
15329   if (vam->async_mode)
15330     {
15331       vam->async_errors += (retval < 0);
15332     }
15333   else
15334     {
15335       vam->retval = retval;
15336       vam->result_ready = 1;
15337     }
15338 }
15339
15340 static void vl_api_map_add_domain_reply_t_handler_json
15341   (vl_api_map_add_domain_reply_t * mp)
15342 {
15343   vat_main_t *vam = &vat_main;
15344   vat_json_node_t node;
15345
15346   vat_json_init_object (&node);
15347   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15348   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15349
15350   vat_json_print (vam->ofp, &node);
15351   vat_json_free (&node);
15352
15353   vam->retval = ntohl (mp->retval);
15354   vam->result_ready = 1;
15355 }
15356
15357 static int
15358 api_get_first_msg_id (vat_main_t * vam)
15359 {
15360   vl_api_get_first_msg_id_t *mp;
15361   unformat_input_t *i = vam->input;
15362   u8 *name;
15363   u8 name_set = 0;
15364   int ret;
15365
15366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (i, "client %s", &name))
15369         name_set = 1;
15370       else
15371         break;
15372     }
15373
15374   if (name_set == 0)
15375     {
15376       errmsg ("missing client name");
15377       return -99;
15378     }
15379   vec_add1 (name, 0);
15380
15381   if (vec_len (name) > 63)
15382     {
15383       errmsg ("client name too long");
15384       return -99;
15385     }
15386
15387   M (GET_FIRST_MSG_ID, mp);
15388   clib_memcpy (mp->name, name, vec_len (name));
15389   S (mp);
15390   W (ret);
15391   return ret;
15392 }
15393
15394 static int
15395 api_cop_interface_enable_disable (vat_main_t * vam)
15396 {
15397   unformat_input_t *line_input = vam->input;
15398   vl_api_cop_interface_enable_disable_t *mp;
15399   u32 sw_if_index = ~0;
15400   u8 enable_disable = 1;
15401   int ret;
15402
15403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15404     {
15405       if (unformat (line_input, "disable"))
15406         enable_disable = 0;
15407       if (unformat (line_input, "enable"))
15408         enable_disable = 1;
15409       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15410                          vam, &sw_if_index))
15411         ;
15412       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15413         ;
15414       else
15415         break;
15416     }
15417
15418   if (sw_if_index == ~0)
15419     {
15420       errmsg ("missing interface name or sw_if_index");
15421       return -99;
15422     }
15423
15424   /* Construct the API message */
15425   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15426   mp->sw_if_index = ntohl (sw_if_index);
15427   mp->enable_disable = enable_disable;
15428
15429   /* send it... */
15430   S (mp);
15431   /* Wait for the reply */
15432   W (ret);
15433   return ret;
15434 }
15435
15436 static int
15437 api_cop_whitelist_enable_disable (vat_main_t * vam)
15438 {
15439   unformat_input_t *line_input = vam->input;
15440   vl_api_cop_whitelist_enable_disable_t *mp;
15441   u32 sw_if_index = ~0;
15442   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15443   u32 fib_id = 0;
15444   int ret;
15445
15446   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15447     {
15448       if (unformat (line_input, "ip4"))
15449         ip4 = 1;
15450       else if (unformat (line_input, "ip6"))
15451         ip6 = 1;
15452       else if (unformat (line_input, "default"))
15453         default_cop = 1;
15454       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15455                          vam, &sw_if_index))
15456         ;
15457       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15458         ;
15459       else if (unformat (line_input, "fib-id %d", &fib_id))
15460         ;
15461       else
15462         break;
15463     }
15464
15465   if (sw_if_index == ~0)
15466     {
15467       errmsg ("missing interface name or sw_if_index");
15468       return -99;
15469     }
15470
15471   /* Construct the API message */
15472   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15473   mp->sw_if_index = ntohl (sw_if_index);
15474   mp->fib_id = ntohl (fib_id);
15475   mp->ip4 = ip4;
15476   mp->ip6 = ip6;
15477   mp->default_cop = default_cop;
15478
15479   /* send it... */
15480   S (mp);
15481   /* Wait for the reply */
15482   W (ret);
15483   return ret;
15484 }
15485
15486 static int
15487 api_get_node_graph (vat_main_t * vam)
15488 {
15489   vl_api_get_node_graph_t *mp;
15490   int ret;
15491
15492   M (GET_NODE_GRAPH, mp);
15493
15494   /* send it... */
15495   S (mp);
15496   /* Wait for the reply */
15497   W (ret);
15498   return ret;
15499 }
15500
15501 /* *INDENT-OFF* */
15502 /** Used for parsing LISP eids */
15503 typedef CLIB_PACKED(struct{
15504   u8 addr[16];   /**< eid address */
15505   u32 len;       /**< prefix length if IP */
15506   u8 type;      /**< type of eid */
15507 }) lisp_eid_vat_t;
15508 /* *INDENT-ON* */
15509
15510 static uword
15511 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15512 {
15513   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15514
15515   memset (a, 0, sizeof (a[0]));
15516
15517   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15518     {
15519       a->type = 0;              /* ipv4 type */
15520     }
15521   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15522     {
15523       a->type = 1;              /* ipv6 type */
15524     }
15525   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15526     {
15527       a->type = 2;              /* mac type */
15528     }
15529   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15530     {
15531       a->type = 3;              /* NSH type */
15532       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15533       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15534     }
15535   else
15536     {
15537       return 0;
15538     }
15539
15540   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15541     {
15542       return 0;
15543     }
15544
15545   return 1;
15546 }
15547
15548 static int
15549 lisp_eid_size_vat (u8 type)
15550 {
15551   switch (type)
15552     {
15553     case 0:
15554       return 4;
15555     case 1:
15556       return 16;
15557     case 2:
15558       return 6;
15559     case 3:
15560       return 5;
15561     }
15562   return 0;
15563 }
15564
15565 static void
15566 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15567 {
15568   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15569 }
15570
15571 static int
15572 api_one_add_del_locator_set (vat_main_t * vam)
15573 {
15574   unformat_input_t *input = vam->input;
15575   vl_api_one_add_del_locator_set_t *mp;
15576   u8 is_add = 1;
15577   u8 *locator_set_name = NULL;
15578   u8 locator_set_name_set = 0;
15579   vl_api_local_locator_t locator, *locators = 0;
15580   u32 sw_if_index, priority, weight;
15581   u32 data_len = 0;
15582
15583   int ret;
15584   /* Parse args required to build the message */
15585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (input, "del"))
15588         {
15589           is_add = 0;
15590         }
15591       else if (unformat (input, "locator-set %s", &locator_set_name))
15592         {
15593           locator_set_name_set = 1;
15594         }
15595       else if (unformat (input, "sw_if_index %u p %u w %u",
15596                          &sw_if_index, &priority, &weight))
15597         {
15598           locator.sw_if_index = htonl (sw_if_index);
15599           locator.priority = priority;
15600           locator.weight = weight;
15601           vec_add1 (locators, locator);
15602         }
15603       else
15604         if (unformat
15605             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15606              &sw_if_index, &priority, &weight))
15607         {
15608           locator.sw_if_index = htonl (sw_if_index);
15609           locator.priority = priority;
15610           locator.weight = weight;
15611           vec_add1 (locators, locator);
15612         }
15613       else
15614         break;
15615     }
15616
15617   if (locator_set_name_set == 0)
15618     {
15619       errmsg ("missing locator-set name");
15620       vec_free (locators);
15621       return -99;
15622     }
15623
15624   if (vec_len (locator_set_name) > 64)
15625     {
15626       errmsg ("locator-set name too long");
15627       vec_free (locator_set_name);
15628       vec_free (locators);
15629       return -99;
15630     }
15631   vec_add1 (locator_set_name, 0);
15632
15633   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15634
15635   /* Construct the API message */
15636   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15637
15638   mp->is_add = is_add;
15639   clib_memcpy (mp->locator_set_name, locator_set_name,
15640                vec_len (locator_set_name));
15641   vec_free (locator_set_name);
15642
15643   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15644   if (locators)
15645     clib_memcpy (mp->locators, locators, data_len);
15646   vec_free (locators);
15647
15648   /* send it... */
15649   S (mp);
15650
15651   /* Wait for a reply... */
15652   W (ret);
15653   return ret;
15654 }
15655
15656 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15657
15658 static int
15659 api_one_add_del_locator (vat_main_t * vam)
15660 {
15661   unformat_input_t *input = vam->input;
15662   vl_api_one_add_del_locator_t *mp;
15663   u32 tmp_if_index = ~0;
15664   u32 sw_if_index = ~0;
15665   u8 sw_if_index_set = 0;
15666   u8 sw_if_index_if_name_set = 0;
15667   u32 priority = ~0;
15668   u8 priority_set = 0;
15669   u32 weight = ~0;
15670   u8 weight_set = 0;
15671   u8 is_add = 1;
15672   u8 *locator_set_name = NULL;
15673   u8 locator_set_name_set = 0;
15674   int ret;
15675
15676   /* Parse args required to build the message */
15677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15678     {
15679       if (unformat (input, "del"))
15680         {
15681           is_add = 0;
15682         }
15683       else if (unformat (input, "locator-set %s", &locator_set_name))
15684         {
15685           locator_set_name_set = 1;
15686         }
15687       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15688                          &tmp_if_index))
15689         {
15690           sw_if_index_if_name_set = 1;
15691           sw_if_index = tmp_if_index;
15692         }
15693       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15694         {
15695           sw_if_index_set = 1;
15696           sw_if_index = tmp_if_index;
15697         }
15698       else if (unformat (input, "p %d", &priority))
15699         {
15700           priority_set = 1;
15701         }
15702       else if (unformat (input, "w %d", &weight))
15703         {
15704           weight_set = 1;
15705         }
15706       else
15707         break;
15708     }
15709
15710   if (locator_set_name_set == 0)
15711     {
15712       errmsg ("missing locator-set name");
15713       return -99;
15714     }
15715
15716   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15717     {
15718       errmsg ("missing sw_if_index");
15719       vec_free (locator_set_name);
15720       return -99;
15721     }
15722
15723   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15724     {
15725       errmsg ("cannot use both params interface name and sw_if_index");
15726       vec_free (locator_set_name);
15727       return -99;
15728     }
15729
15730   if (priority_set == 0)
15731     {
15732       errmsg ("missing locator-set priority");
15733       vec_free (locator_set_name);
15734       return -99;
15735     }
15736
15737   if (weight_set == 0)
15738     {
15739       errmsg ("missing locator-set weight");
15740       vec_free (locator_set_name);
15741       return -99;
15742     }
15743
15744   if (vec_len (locator_set_name) > 64)
15745     {
15746       errmsg ("locator-set name too long");
15747       vec_free (locator_set_name);
15748       return -99;
15749     }
15750   vec_add1 (locator_set_name, 0);
15751
15752   /* Construct the API message */
15753   M (ONE_ADD_DEL_LOCATOR, mp);
15754
15755   mp->is_add = is_add;
15756   mp->sw_if_index = ntohl (sw_if_index);
15757   mp->priority = priority;
15758   mp->weight = weight;
15759   clib_memcpy (mp->locator_set_name, locator_set_name,
15760                vec_len (locator_set_name));
15761   vec_free (locator_set_name);
15762
15763   /* send it... */
15764   S (mp);
15765
15766   /* Wait for a reply... */
15767   W (ret);
15768   return ret;
15769 }
15770
15771 #define api_lisp_add_del_locator api_one_add_del_locator
15772
15773 uword
15774 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15775 {
15776   u32 *key_id = va_arg (*args, u32 *);
15777   u8 *s = 0;
15778
15779   if (unformat (input, "%s", &s))
15780     {
15781       if (!strcmp ((char *) s, "sha1"))
15782         key_id[0] = HMAC_SHA_1_96;
15783       else if (!strcmp ((char *) s, "sha256"))
15784         key_id[0] = HMAC_SHA_256_128;
15785       else
15786         {
15787           clib_warning ("invalid key_id: '%s'", s);
15788           key_id[0] = HMAC_NO_KEY;
15789         }
15790     }
15791   else
15792     return 0;
15793
15794   vec_free (s);
15795   return 1;
15796 }
15797
15798 static int
15799 api_one_add_del_local_eid (vat_main_t * vam)
15800 {
15801   unformat_input_t *input = vam->input;
15802   vl_api_one_add_del_local_eid_t *mp;
15803   u8 is_add = 1;
15804   u8 eid_set = 0;
15805   lisp_eid_vat_t _eid, *eid = &_eid;
15806   u8 *locator_set_name = 0;
15807   u8 locator_set_name_set = 0;
15808   u32 vni = 0;
15809   u16 key_id = 0;
15810   u8 *key = 0;
15811   int ret;
15812
15813   /* Parse args required to build the message */
15814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15815     {
15816       if (unformat (input, "del"))
15817         {
15818           is_add = 0;
15819         }
15820       else if (unformat (input, "vni %d", &vni))
15821         {
15822           ;
15823         }
15824       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15825         {
15826           eid_set = 1;
15827         }
15828       else if (unformat (input, "locator-set %s", &locator_set_name))
15829         {
15830           locator_set_name_set = 1;
15831         }
15832       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15833         ;
15834       else if (unformat (input, "secret-key %_%v%_", &key))
15835         ;
15836       else
15837         break;
15838     }
15839
15840   if (locator_set_name_set == 0)
15841     {
15842       errmsg ("missing locator-set name");
15843       return -99;
15844     }
15845
15846   if (0 == eid_set)
15847     {
15848       errmsg ("EID address not set!");
15849       vec_free (locator_set_name);
15850       return -99;
15851     }
15852
15853   if (key && (0 == key_id))
15854     {
15855       errmsg ("invalid key_id!");
15856       return -99;
15857     }
15858
15859   if (vec_len (key) > 64)
15860     {
15861       errmsg ("key too long");
15862       vec_free (key);
15863       return -99;
15864     }
15865
15866   if (vec_len (locator_set_name) > 64)
15867     {
15868       errmsg ("locator-set name too long");
15869       vec_free (locator_set_name);
15870       return -99;
15871     }
15872   vec_add1 (locator_set_name, 0);
15873
15874   /* Construct the API message */
15875   M (ONE_ADD_DEL_LOCAL_EID, mp);
15876
15877   mp->is_add = is_add;
15878   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15879   mp->eid_type = eid->type;
15880   mp->prefix_len = eid->len;
15881   mp->vni = clib_host_to_net_u32 (vni);
15882   mp->key_id = clib_host_to_net_u16 (key_id);
15883   clib_memcpy (mp->locator_set_name, locator_set_name,
15884                vec_len (locator_set_name));
15885   clib_memcpy (mp->key, key, vec_len (key));
15886
15887   vec_free (locator_set_name);
15888   vec_free (key);
15889
15890   /* send it... */
15891   S (mp);
15892
15893   /* Wait for a reply... */
15894   W (ret);
15895   return ret;
15896 }
15897
15898 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15899
15900 static int
15901 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15902 {
15903   u32 dp_table = 0, vni = 0;;
15904   unformat_input_t *input = vam->input;
15905   vl_api_gpe_add_del_fwd_entry_t *mp;
15906   u8 is_add = 1;
15907   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15908   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15909   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15910   u32 action = ~0, w;
15911   ip4_address_t rmt_rloc4, lcl_rloc4;
15912   ip6_address_t rmt_rloc6, lcl_rloc6;
15913   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15914   int ret;
15915
15916   memset (&rloc, 0, sizeof (rloc));
15917
15918   /* Parse args required to build the message */
15919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15920     {
15921       if (unformat (input, "del"))
15922         is_add = 0;
15923       else if (unformat (input, "add"))
15924         is_add = 1;
15925       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15926         {
15927           rmt_eid_set = 1;
15928         }
15929       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15930         {
15931           lcl_eid_set = 1;
15932         }
15933       else if (unformat (input, "vrf %d", &dp_table))
15934         ;
15935       else if (unformat (input, "bd %d", &dp_table))
15936         ;
15937       else if (unformat (input, "vni %d", &vni))
15938         ;
15939       else if (unformat (input, "w %d", &w))
15940         {
15941           if (!curr_rloc)
15942             {
15943               errmsg ("No RLOC configured for setting priority/weight!");
15944               return -99;
15945             }
15946           curr_rloc->weight = w;
15947         }
15948       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15949                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15950         {
15951           rloc.is_ip4 = 1;
15952
15953           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15954           rloc.weight = 0;
15955           vec_add1 (lcl_locs, rloc);
15956
15957           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15958           vec_add1 (rmt_locs, rloc);
15959           /* weight saved in rmt loc */
15960           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15961         }
15962       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15963                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15964         {
15965           rloc.is_ip4 = 0;
15966           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15967           rloc.weight = 0;
15968           vec_add1 (lcl_locs, rloc);
15969
15970           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15971           vec_add1 (rmt_locs, rloc);
15972           /* weight saved in rmt loc */
15973           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15974         }
15975       else if (unformat (input, "action %d", &action))
15976         {
15977           ;
15978         }
15979       else
15980         {
15981           clib_warning ("parse error '%U'", format_unformat_error, input);
15982           return -99;
15983         }
15984     }
15985
15986   if (!rmt_eid_set)
15987     {
15988       errmsg ("remote eid addresses not set");
15989       return -99;
15990     }
15991
15992   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15993     {
15994       errmsg ("eid types don't match");
15995       return -99;
15996     }
15997
15998   if (0 == rmt_locs && (u32) ~ 0 == action)
15999     {
16000       errmsg ("action not set for negative mapping");
16001       return -99;
16002     }
16003
16004   /* Construct the API message */
16005   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16006       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16007
16008   mp->is_add = is_add;
16009   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16010   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16011   mp->eid_type = rmt_eid->type;
16012   mp->dp_table = clib_host_to_net_u32 (dp_table);
16013   mp->vni = clib_host_to_net_u32 (vni);
16014   mp->rmt_len = rmt_eid->len;
16015   mp->lcl_len = lcl_eid->len;
16016   mp->action = action;
16017
16018   if (0 != rmt_locs && 0 != lcl_locs)
16019     {
16020       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16021       clib_memcpy (mp->locs, lcl_locs,
16022                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16023
16024       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16025       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16026                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16027     }
16028   vec_free (lcl_locs);
16029   vec_free (rmt_locs);
16030
16031   /* send it... */
16032   S (mp);
16033
16034   /* Wait for a reply... */
16035   W (ret);
16036   return ret;
16037 }
16038
16039 static int
16040 api_one_add_del_map_server (vat_main_t * vam)
16041 {
16042   unformat_input_t *input = vam->input;
16043   vl_api_one_add_del_map_server_t *mp;
16044   u8 is_add = 1;
16045   u8 ipv4_set = 0;
16046   u8 ipv6_set = 0;
16047   ip4_address_t ipv4;
16048   ip6_address_t ipv6;
16049   int ret;
16050
16051   /* Parse args required to build the message */
16052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16053     {
16054       if (unformat (input, "del"))
16055         {
16056           is_add = 0;
16057         }
16058       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16059         {
16060           ipv4_set = 1;
16061         }
16062       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16063         {
16064           ipv6_set = 1;
16065         }
16066       else
16067         break;
16068     }
16069
16070   if (ipv4_set && ipv6_set)
16071     {
16072       errmsg ("both eid v4 and v6 addresses set");
16073       return -99;
16074     }
16075
16076   if (!ipv4_set && !ipv6_set)
16077     {
16078       errmsg ("eid addresses not set");
16079       return -99;
16080     }
16081
16082   /* Construct the API message */
16083   M (ONE_ADD_DEL_MAP_SERVER, mp);
16084
16085   mp->is_add = is_add;
16086   if (ipv6_set)
16087     {
16088       mp->is_ipv6 = 1;
16089       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16090     }
16091   else
16092     {
16093       mp->is_ipv6 = 0;
16094       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16095     }
16096
16097   /* send it... */
16098   S (mp);
16099
16100   /* Wait for a reply... */
16101   W (ret);
16102   return ret;
16103 }
16104
16105 #define api_lisp_add_del_map_server api_one_add_del_map_server
16106
16107 static int
16108 api_one_add_del_map_resolver (vat_main_t * vam)
16109 {
16110   unformat_input_t *input = vam->input;
16111   vl_api_one_add_del_map_resolver_t *mp;
16112   u8 is_add = 1;
16113   u8 ipv4_set = 0;
16114   u8 ipv6_set = 0;
16115   ip4_address_t ipv4;
16116   ip6_address_t ipv6;
16117   int ret;
16118
16119   /* Parse args required to build the message */
16120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16121     {
16122       if (unformat (input, "del"))
16123         {
16124           is_add = 0;
16125         }
16126       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16127         {
16128           ipv4_set = 1;
16129         }
16130       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16131         {
16132           ipv6_set = 1;
16133         }
16134       else
16135         break;
16136     }
16137
16138   if (ipv4_set && ipv6_set)
16139     {
16140       errmsg ("both eid v4 and v6 addresses set");
16141       return -99;
16142     }
16143
16144   if (!ipv4_set && !ipv6_set)
16145     {
16146       errmsg ("eid addresses not set");
16147       return -99;
16148     }
16149
16150   /* Construct the API message */
16151   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16152
16153   mp->is_add = is_add;
16154   if (ipv6_set)
16155     {
16156       mp->is_ipv6 = 1;
16157       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16158     }
16159   else
16160     {
16161       mp->is_ipv6 = 0;
16162       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16163     }
16164
16165   /* send it... */
16166   S (mp);
16167
16168   /* Wait for a reply... */
16169   W (ret);
16170   return ret;
16171 }
16172
16173 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16174
16175 static int
16176 api_lisp_gpe_enable_disable (vat_main_t * vam)
16177 {
16178   unformat_input_t *input = vam->input;
16179   vl_api_gpe_enable_disable_t *mp;
16180   u8 is_set = 0;
16181   u8 is_en = 1;
16182   int ret;
16183
16184   /* Parse args required to build the message */
16185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16186     {
16187       if (unformat (input, "enable"))
16188         {
16189           is_set = 1;
16190           is_en = 1;
16191         }
16192       else if (unformat (input, "disable"))
16193         {
16194           is_set = 1;
16195           is_en = 0;
16196         }
16197       else
16198         break;
16199     }
16200
16201   if (is_set == 0)
16202     {
16203       errmsg ("Value not set");
16204       return -99;
16205     }
16206
16207   /* Construct the API message */
16208   M (GPE_ENABLE_DISABLE, mp);
16209
16210   mp->is_en = is_en;
16211
16212   /* send it... */
16213   S (mp);
16214
16215   /* Wait for a reply... */
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16222 {
16223   unformat_input_t *input = vam->input;
16224   vl_api_one_rloc_probe_enable_disable_t *mp;
16225   u8 is_set = 0;
16226   u8 is_en = 0;
16227   int ret;
16228
16229   /* Parse args required to build the message */
16230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16231     {
16232       if (unformat (input, "enable"))
16233         {
16234           is_set = 1;
16235           is_en = 1;
16236         }
16237       else if (unformat (input, "disable"))
16238         is_set = 1;
16239       else
16240         break;
16241     }
16242
16243   if (!is_set)
16244     {
16245       errmsg ("Value not set");
16246       return -99;
16247     }
16248
16249   /* Construct the API message */
16250   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16251
16252   mp->is_enabled = is_en;
16253
16254   /* send it... */
16255   S (mp);
16256
16257   /* Wait for a reply... */
16258   W (ret);
16259   return ret;
16260 }
16261
16262 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16263
16264 static int
16265 api_one_map_register_enable_disable (vat_main_t * vam)
16266 {
16267   unformat_input_t *input = vam->input;
16268   vl_api_one_map_register_enable_disable_t *mp;
16269   u8 is_set = 0;
16270   u8 is_en = 0;
16271   int ret;
16272
16273   /* Parse args required to build the message */
16274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16275     {
16276       if (unformat (input, "enable"))
16277         {
16278           is_set = 1;
16279           is_en = 1;
16280         }
16281       else if (unformat (input, "disable"))
16282         is_set = 1;
16283       else
16284         break;
16285     }
16286
16287   if (!is_set)
16288     {
16289       errmsg ("Value not set");
16290       return -99;
16291     }
16292
16293   /* Construct the API message */
16294   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16295
16296   mp->is_enabled = is_en;
16297
16298   /* send it... */
16299   S (mp);
16300
16301   /* Wait for a reply... */
16302   W (ret);
16303   return ret;
16304 }
16305
16306 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16307
16308 static int
16309 api_one_enable_disable (vat_main_t * vam)
16310 {
16311   unformat_input_t *input = vam->input;
16312   vl_api_one_enable_disable_t *mp;
16313   u8 is_set = 0;
16314   u8 is_en = 0;
16315   int ret;
16316
16317   /* Parse args required to build the message */
16318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16319     {
16320       if (unformat (input, "enable"))
16321         {
16322           is_set = 1;
16323           is_en = 1;
16324         }
16325       else if (unformat (input, "disable"))
16326         {
16327           is_set = 1;
16328         }
16329       else
16330         break;
16331     }
16332
16333   if (!is_set)
16334     {
16335       errmsg ("Value not set");
16336       return -99;
16337     }
16338
16339   /* Construct the API message */
16340   M (ONE_ENABLE_DISABLE, mp);
16341
16342   mp->is_en = is_en;
16343
16344   /* send it... */
16345   S (mp);
16346
16347   /* Wait for a reply... */
16348   W (ret);
16349   return ret;
16350 }
16351
16352 #define api_lisp_enable_disable api_one_enable_disable
16353
16354 static int
16355 api_show_one_map_register_state (vat_main_t * vam)
16356 {
16357   vl_api_show_one_map_register_state_t *mp;
16358   int ret;
16359
16360   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16361
16362   /* send */
16363   S (mp);
16364
16365   /* wait for reply */
16366   W (ret);
16367   return ret;
16368 }
16369
16370 #define api_show_lisp_map_register_state api_show_one_map_register_state
16371
16372 static int
16373 api_show_one_rloc_probe_state (vat_main_t * vam)
16374 {
16375   vl_api_show_one_rloc_probe_state_t *mp;
16376   int ret;
16377
16378   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16379
16380   /* send */
16381   S (mp);
16382
16383   /* wait for reply */
16384   W (ret);
16385   return ret;
16386 }
16387
16388 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16389
16390 static int
16391 api_one_add_del_ndp_entry (vat_main_t * vam)
16392 {
16393   vl_api_one_add_del_ndp_entry_t *mp;
16394   unformat_input_t *input = vam->input;
16395   u8 is_add = 1;
16396   u8 mac_set = 0;
16397   u8 bd_set = 0;
16398   u8 ip_set = 0;
16399   u8 mac[6] = { 0, };
16400   u8 ip6[16] = { 0, };
16401   u32 bd = ~0;
16402   int ret;
16403
16404   /* Parse args required to build the message */
16405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16406     {
16407       if (unformat (input, "del"))
16408         is_add = 0;
16409       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16410         mac_set = 1;
16411       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16412         ip_set = 1;
16413       else if (unformat (input, "bd %d", &bd))
16414         bd_set = 1;
16415       else
16416         {
16417           errmsg ("parse error '%U'", format_unformat_error, input);
16418           return -99;
16419         }
16420     }
16421
16422   if (!bd_set || !ip_set || (!mac_set && is_add))
16423     {
16424       errmsg ("Missing BD, IP or MAC!");
16425       return -99;
16426     }
16427
16428   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16429   mp->is_add = is_add;
16430   clib_memcpy (mp->mac, mac, 6);
16431   mp->bd = clib_host_to_net_u32 (bd);
16432   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16433
16434   /* send */
16435   S (mp);
16436
16437   /* wait for reply */
16438   W (ret);
16439   return ret;
16440 }
16441
16442 static int
16443 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16444 {
16445   vl_api_one_add_del_l2_arp_entry_t *mp;
16446   unformat_input_t *input = vam->input;
16447   u8 is_add = 1;
16448   u8 mac_set = 0;
16449   u8 bd_set = 0;
16450   u8 ip_set = 0;
16451   u8 mac[6] = { 0, };
16452   u32 ip4 = 0, bd = ~0;
16453   int ret;
16454
16455   /* Parse args required to build the message */
16456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16457     {
16458       if (unformat (input, "del"))
16459         is_add = 0;
16460       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16461         mac_set = 1;
16462       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16463         ip_set = 1;
16464       else if (unformat (input, "bd %d", &bd))
16465         bd_set = 1;
16466       else
16467         {
16468           errmsg ("parse error '%U'", format_unformat_error, input);
16469           return -99;
16470         }
16471     }
16472
16473   if (!bd_set || !ip_set || (!mac_set && is_add))
16474     {
16475       errmsg ("Missing BD, IP or MAC!");
16476       return -99;
16477     }
16478
16479   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16480   mp->is_add = is_add;
16481   clib_memcpy (mp->mac, mac, 6);
16482   mp->bd = clib_host_to_net_u32 (bd);
16483   mp->ip4 = ip4;
16484
16485   /* send */
16486   S (mp);
16487
16488   /* wait for reply */
16489   W (ret);
16490   return ret;
16491 }
16492
16493 static int
16494 api_one_ndp_bd_get (vat_main_t * vam)
16495 {
16496   vl_api_one_ndp_bd_get_t *mp;
16497   int ret;
16498
16499   M (ONE_NDP_BD_GET, mp);
16500
16501   /* send */
16502   S (mp);
16503
16504   /* wait for reply */
16505   W (ret);
16506   return ret;
16507 }
16508
16509 static int
16510 api_one_ndp_entries_get (vat_main_t * vam)
16511 {
16512   vl_api_one_ndp_entries_get_t *mp;
16513   unformat_input_t *input = vam->input;
16514   u8 bd_set = 0;
16515   u32 bd = ~0;
16516   int ret;
16517
16518   /* Parse args required to build the message */
16519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16520     {
16521       if (unformat (input, "bd %d", &bd))
16522         bd_set = 1;
16523       else
16524         {
16525           errmsg ("parse error '%U'", format_unformat_error, input);
16526           return -99;
16527         }
16528     }
16529
16530   if (!bd_set)
16531     {
16532       errmsg ("Expected bridge domain!");
16533       return -99;
16534     }
16535
16536   M (ONE_NDP_ENTRIES_GET, mp);
16537   mp->bd = clib_host_to_net_u32 (bd);
16538
16539   /* send */
16540   S (mp);
16541
16542   /* wait for reply */
16543   W (ret);
16544   return ret;
16545 }
16546
16547 static int
16548 api_one_l2_arp_bd_get (vat_main_t * vam)
16549 {
16550   vl_api_one_l2_arp_bd_get_t *mp;
16551   int ret;
16552
16553   M (ONE_L2_ARP_BD_GET, mp);
16554
16555   /* send */
16556   S (mp);
16557
16558   /* wait for reply */
16559   W (ret);
16560   return ret;
16561 }
16562
16563 static int
16564 api_one_l2_arp_entries_get (vat_main_t * vam)
16565 {
16566   vl_api_one_l2_arp_entries_get_t *mp;
16567   unformat_input_t *input = vam->input;
16568   u8 bd_set = 0;
16569   u32 bd = ~0;
16570   int ret;
16571
16572   /* Parse args required to build the message */
16573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (input, "bd %d", &bd))
16576         bd_set = 1;
16577       else
16578         {
16579           errmsg ("parse error '%U'", format_unformat_error, input);
16580           return -99;
16581         }
16582     }
16583
16584   if (!bd_set)
16585     {
16586       errmsg ("Expected bridge domain!");
16587       return -99;
16588     }
16589
16590   M (ONE_L2_ARP_ENTRIES_GET, mp);
16591   mp->bd = clib_host_to_net_u32 (bd);
16592
16593   /* send */
16594   S (mp);
16595
16596   /* wait for reply */
16597   W (ret);
16598   return ret;
16599 }
16600
16601 static int
16602 api_one_stats_enable_disable (vat_main_t * vam)
16603 {
16604   vl_api_one_stats_enable_disable_t *mp;
16605   unformat_input_t *input = vam->input;
16606   u8 is_set = 0;
16607   u8 is_en = 0;
16608   int ret;
16609
16610   /* Parse args required to build the message */
16611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16612     {
16613       if (unformat (input, "enable"))
16614         {
16615           is_set = 1;
16616           is_en = 1;
16617         }
16618       else if (unformat (input, "disable"))
16619         {
16620           is_set = 1;
16621         }
16622       else
16623         break;
16624     }
16625
16626   if (!is_set)
16627     {
16628       errmsg ("Value not set");
16629       return -99;
16630     }
16631
16632   M (ONE_STATS_ENABLE_DISABLE, mp);
16633   mp->is_en = is_en;
16634
16635   /* send */
16636   S (mp);
16637
16638   /* wait for reply */
16639   W (ret);
16640   return ret;
16641 }
16642
16643 static int
16644 api_show_one_stats_enable_disable (vat_main_t * vam)
16645 {
16646   vl_api_show_one_stats_enable_disable_t *mp;
16647   int ret;
16648
16649   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16650
16651   /* send */
16652   S (mp);
16653
16654   /* wait for reply */
16655   W (ret);
16656   return ret;
16657 }
16658
16659 static int
16660 api_show_one_map_request_mode (vat_main_t * vam)
16661 {
16662   vl_api_show_one_map_request_mode_t *mp;
16663   int ret;
16664
16665   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16666
16667   /* send */
16668   S (mp);
16669
16670   /* wait for reply */
16671   W (ret);
16672   return ret;
16673 }
16674
16675 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16676
16677 static int
16678 api_one_map_request_mode (vat_main_t * vam)
16679 {
16680   unformat_input_t *input = vam->input;
16681   vl_api_one_map_request_mode_t *mp;
16682   u8 mode = 0;
16683   int ret;
16684
16685   /* Parse args required to build the message */
16686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16687     {
16688       if (unformat (input, "dst-only"))
16689         mode = 0;
16690       else if (unformat (input, "src-dst"))
16691         mode = 1;
16692       else
16693         {
16694           errmsg ("parse error '%U'", format_unformat_error, input);
16695           return -99;
16696         }
16697     }
16698
16699   M (ONE_MAP_REQUEST_MODE, mp);
16700
16701   mp->mode = mode;
16702
16703   /* send */
16704   S (mp);
16705
16706   /* wait for reply */
16707   W (ret);
16708   return ret;
16709 }
16710
16711 #define api_lisp_map_request_mode api_one_map_request_mode
16712
16713 /**
16714  * Enable/disable ONE proxy ITR.
16715  *
16716  * @param vam vpp API test context
16717  * @return return code
16718  */
16719 static int
16720 api_one_pitr_set_locator_set (vat_main_t * vam)
16721 {
16722   u8 ls_name_set = 0;
16723   unformat_input_t *input = vam->input;
16724   vl_api_one_pitr_set_locator_set_t *mp;
16725   u8 is_add = 1;
16726   u8 *ls_name = 0;
16727   int ret;
16728
16729   /* Parse args required to build the message */
16730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16731     {
16732       if (unformat (input, "del"))
16733         is_add = 0;
16734       else if (unformat (input, "locator-set %s", &ls_name))
16735         ls_name_set = 1;
16736       else
16737         {
16738           errmsg ("parse error '%U'", format_unformat_error, input);
16739           return -99;
16740         }
16741     }
16742
16743   if (!ls_name_set)
16744     {
16745       errmsg ("locator-set name not set!");
16746       return -99;
16747     }
16748
16749   M (ONE_PITR_SET_LOCATOR_SET, mp);
16750
16751   mp->is_add = is_add;
16752   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16753   vec_free (ls_name);
16754
16755   /* send */
16756   S (mp);
16757
16758   /* wait for reply */
16759   W (ret);
16760   return ret;
16761 }
16762
16763 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16764
16765 static int
16766 api_one_nsh_set_locator_set (vat_main_t * vam)
16767 {
16768   u8 ls_name_set = 0;
16769   unformat_input_t *input = vam->input;
16770   vl_api_one_nsh_set_locator_set_t *mp;
16771   u8 is_add = 1;
16772   u8 *ls_name = 0;
16773   int ret;
16774
16775   /* Parse args required to build the message */
16776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16777     {
16778       if (unformat (input, "del"))
16779         is_add = 0;
16780       else if (unformat (input, "ls %s", &ls_name))
16781         ls_name_set = 1;
16782       else
16783         {
16784           errmsg ("parse error '%U'", format_unformat_error, input);
16785           return -99;
16786         }
16787     }
16788
16789   if (!ls_name_set && is_add)
16790     {
16791       errmsg ("locator-set name not set!");
16792       return -99;
16793     }
16794
16795   M (ONE_NSH_SET_LOCATOR_SET, mp);
16796
16797   mp->is_add = is_add;
16798   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16799   vec_free (ls_name);
16800
16801   /* send */
16802   S (mp);
16803
16804   /* wait for reply */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 static int
16810 api_show_one_pitr (vat_main_t * vam)
16811 {
16812   vl_api_show_one_pitr_t *mp;
16813   int ret;
16814
16815   if (!vam->json_output)
16816     {
16817       print (vam->ofp, "%=20s", "lisp status:");
16818     }
16819
16820   M (SHOW_ONE_PITR, mp);
16821   /* send it... */
16822   S (mp);
16823
16824   /* Wait for a reply... */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 #define api_show_lisp_pitr api_show_one_pitr
16830
16831 static int
16832 api_one_use_petr (vat_main_t * vam)
16833 {
16834   unformat_input_t *input = vam->input;
16835   vl_api_one_use_petr_t *mp;
16836   u8 is_add = 0;
16837   ip_address_t ip;
16838   int ret;
16839
16840   memset (&ip, 0, sizeof (ip));
16841
16842   /* Parse args required to build the message */
16843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16844     {
16845       if (unformat (input, "disable"))
16846         is_add = 0;
16847       else
16848         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16849         {
16850           is_add = 1;
16851           ip_addr_version (&ip) = IP4;
16852         }
16853       else
16854         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16855         {
16856           is_add = 1;
16857           ip_addr_version (&ip) = IP6;
16858         }
16859       else
16860         {
16861           errmsg ("parse error '%U'", format_unformat_error, input);
16862           return -99;
16863         }
16864     }
16865
16866   M (ONE_USE_PETR, mp);
16867
16868   mp->is_add = is_add;
16869   if (is_add)
16870     {
16871       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16872       if (mp->is_ip4)
16873         clib_memcpy (mp->address, &ip, 4);
16874       else
16875         clib_memcpy (mp->address, &ip, 16);
16876     }
16877
16878   /* send */
16879   S (mp);
16880
16881   /* wait for reply */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 #define api_lisp_use_petr api_one_use_petr
16887
16888 static int
16889 api_show_one_nsh_mapping (vat_main_t * vam)
16890 {
16891   vl_api_show_one_use_petr_t *mp;
16892   int ret;
16893
16894   if (!vam->json_output)
16895     {
16896       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16897     }
16898
16899   M (SHOW_ONE_NSH_MAPPING, mp);
16900   /* send it... */
16901   S (mp);
16902
16903   /* Wait for a reply... */
16904   W (ret);
16905   return ret;
16906 }
16907
16908 static int
16909 api_show_one_use_petr (vat_main_t * vam)
16910 {
16911   vl_api_show_one_use_petr_t *mp;
16912   int ret;
16913
16914   if (!vam->json_output)
16915     {
16916       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16917     }
16918
16919   M (SHOW_ONE_USE_PETR, mp);
16920   /* send it... */
16921   S (mp);
16922
16923   /* Wait for a reply... */
16924   W (ret);
16925   return ret;
16926 }
16927
16928 #define api_show_lisp_use_petr api_show_one_use_petr
16929
16930 /**
16931  * Add/delete mapping between vni and vrf
16932  */
16933 static int
16934 api_one_eid_table_add_del_map (vat_main_t * vam)
16935 {
16936   unformat_input_t *input = vam->input;
16937   vl_api_one_eid_table_add_del_map_t *mp;
16938   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16939   u32 vni, vrf, bd_index;
16940   int ret;
16941
16942   /* Parse args required to build the message */
16943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16944     {
16945       if (unformat (input, "del"))
16946         is_add = 0;
16947       else if (unformat (input, "vrf %d", &vrf))
16948         vrf_set = 1;
16949       else if (unformat (input, "bd_index %d", &bd_index))
16950         bd_index_set = 1;
16951       else if (unformat (input, "vni %d", &vni))
16952         vni_set = 1;
16953       else
16954         break;
16955     }
16956
16957   if (!vni_set || (!vrf_set && !bd_index_set))
16958     {
16959       errmsg ("missing arguments!");
16960       return -99;
16961     }
16962
16963   if (vrf_set && bd_index_set)
16964     {
16965       errmsg ("error: both vrf and bd entered!");
16966       return -99;
16967     }
16968
16969   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16970
16971   mp->is_add = is_add;
16972   mp->vni = htonl (vni);
16973   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16974   mp->is_l2 = bd_index_set;
16975
16976   /* send */
16977   S (mp);
16978
16979   /* wait for reply */
16980   W (ret);
16981   return ret;
16982 }
16983
16984 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16985
16986 uword
16987 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16988 {
16989   u32 *action = va_arg (*args, u32 *);
16990   u8 *s = 0;
16991
16992   if (unformat (input, "%s", &s))
16993     {
16994       if (!strcmp ((char *) s, "no-action"))
16995         action[0] = 0;
16996       else if (!strcmp ((char *) s, "natively-forward"))
16997         action[0] = 1;
16998       else if (!strcmp ((char *) s, "send-map-request"))
16999         action[0] = 2;
17000       else if (!strcmp ((char *) s, "drop"))
17001         action[0] = 3;
17002       else
17003         {
17004           clib_warning ("invalid action: '%s'", s);
17005           action[0] = 3;
17006         }
17007     }
17008   else
17009     return 0;
17010
17011   vec_free (s);
17012   return 1;
17013 }
17014
17015 /**
17016  * Add/del remote mapping to/from ONE control plane
17017  *
17018  * @param vam vpp API test context
17019  * @return return code
17020  */
17021 static int
17022 api_one_add_del_remote_mapping (vat_main_t * vam)
17023 {
17024   unformat_input_t *input = vam->input;
17025   vl_api_one_add_del_remote_mapping_t *mp;
17026   u32 vni = 0;
17027   lisp_eid_vat_t _eid, *eid = &_eid;
17028   lisp_eid_vat_t _seid, *seid = &_seid;
17029   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17030   u32 action = ~0, p, w, data_len;
17031   ip4_address_t rloc4;
17032   ip6_address_t rloc6;
17033   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17034   int ret;
17035
17036   memset (&rloc, 0, sizeof (rloc));
17037
17038   /* Parse args required to build the message */
17039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17040     {
17041       if (unformat (input, "del-all"))
17042         {
17043           del_all = 1;
17044         }
17045       else if (unformat (input, "del"))
17046         {
17047           is_add = 0;
17048         }
17049       else if (unformat (input, "add"))
17050         {
17051           is_add = 1;
17052         }
17053       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17054         {
17055           eid_set = 1;
17056         }
17057       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17058         {
17059           seid_set = 1;
17060         }
17061       else if (unformat (input, "vni %d", &vni))
17062         {
17063           ;
17064         }
17065       else if (unformat (input, "p %d w %d", &p, &w))
17066         {
17067           if (!curr_rloc)
17068             {
17069               errmsg ("No RLOC configured for setting priority/weight!");
17070               return -99;
17071             }
17072           curr_rloc->priority = p;
17073           curr_rloc->weight = w;
17074         }
17075       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17076         {
17077           rloc.is_ip4 = 1;
17078           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17079           vec_add1 (rlocs, rloc);
17080           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17081         }
17082       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17083         {
17084           rloc.is_ip4 = 0;
17085           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17086           vec_add1 (rlocs, rloc);
17087           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17088         }
17089       else if (unformat (input, "action %U",
17090                          unformat_negative_mapping_action, &action))
17091         {
17092           ;
17093         }
17094       else
17095         {
17096           clib_warning ("parse error '%U'", format_unformat_error, input);
17097           return -99;
17098         }
17099     }
17100
17101   if (0 == eid_set)
17102     {
17103       errmsg ("missing params!");
17104       return -99;
17105     }
17106
17107   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17108     {
17109       errmsg ("no action set for negative map-reply!");
17110       return -99;
17111     }
17112
17113   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17114
17115   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17116   mp->is_add = is_add;
17117   mp->vni = htonl (vni);
17118   mp->action = (u8) action;
17119   mp->is_src_dst = seid_set;
17120   mp->eid_len = eid->len;
17121   mp->seid_len = seid->len;
17122   mp->del_all = del_all;
17123   mp->eid_type = eid->type;
17124   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17125   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17126
17127   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17128   clib_memcpy (mp->rlocs, rlocs, data_len);
17129   vec_free (rlocs);
17130
17131   /* send it... */
17132   S (mp);
17133
17134   /* Wait for a reply... */
17135   W (ret);
17136   return ret;
17137 }
17138
17139 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17140
17141 /**
17142  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17143  * forwarding entries in data-plane accordingly.
17144  *
17145  * @param vam vpp API test context
17146  * @return return code
17147  */
17148 static int
17149 api_one_add_del_adjacency (vat_main_t * vam)
17150 {
17151   unformat_input_t *input = vam->input;
17152   vl_api_one_add_del_adjacency_t *mp;
17153   u32 vni = 0;
17154   ip4_address_t leid4, reid4;
17155   ip6_address_t leid6, reid6;
17156   u8 reid_mac[6] = { 0 };
17157   u8 leid_mac[6] = { 0 };
17158   u8 reid_type, leid_type;
17159   u32 leid_len = 0, reid_len = 0, len;
17160   u8 is_add = 1;
17161   int ret;
17162
17163   leid_type = reid_type = (u8) ~ 0;
17164
17165   /* Parse args required to build the message */
17166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17167     {
17168       if (unformat (input, "del"))
17169         {
17170           is_add = 0;
17171         }
17172       else if (unformat (input, "add"))
17173         {
17174           is_add = 1;
17175         }
17176       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17177                          &reid4, &len))
17178         {
17179           reid_type = 0;        /* ipv4 */
17180           reid_len = len;
17181         }
17182       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17183                          &reid6, &len))
17184         {
17185           reid_type = 1;        /* ipv6 */
17186           reid_len = len;
17187         }
17188       else if (unformat (input, "reid %U", unformat_ethernet_address,
17189                          reid_mac))
17190         {
17191           reid_type = 2;        /* mac */
17192         }
17193       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17194                          &leid4, &len))
17195         {
17196           leid_type = 0;        /* ipv4 */
17197           leid_len = len;
17198         }
17199       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17200                          &leid6, &len))
17201         {
17202           leid_type = 1;        /* ipv6 */
17203           leid_len = len;
17204         }
17205       else if (unformat (input, "leid %U", unformat_ethernet_address,
17206                          leid_mac))
17207         {
17208           leid_type = 2;        /* mac */
17209         }
17210       else if (unformat (input, "vni %d", &vni))
17211         {
17212           ;
17213         }
17214       else
17215         {
17216           errmsg ("parse error '%U'", format_unformat_error, input);
17217           return -99;
17218         }
17219     }
17220
17221   if ((u8) ~ 0 == reid_type)
17222     {
17223       errmsg ("missing params!");
17224       return -99;
17225     }
17226
17227   if (leid_type != reid_type)
17228     {
17229       errmsg ("remote and local EIDs are of different types!");
17230       return -99;
17231     }
17232
17233   M (ONE_ADD_DEL_ADJACENCY, mp);
17234   mp->is_add = is_add;
17235   mp->vni = htonl (vni);
17236   mp->leid_len = leid_len;
17237   mp->reid_len = reid_len;
17238   mp->eid_type = reid_type;
17239
17240   switch (mp->eid_type)
17241     {
17242     case 0:
17243       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17244       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17245       break;
17246     case 1:
17247       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17248       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17249       break;
17250     case 2:
17251       clib_memcpy (mp->leid, leid_mac, 6);
17252       clib_memcpy (mp->reid, reid_mac, 6);
17253       break;
17254     default:
17255       errmsg ("unknown EID type %d!", mp->eid_type);
17256       return 0;
17257     }
17258
17259   /* send it... */
17260   S (mp);
17261
17262   /* Wait for a reply... */
17263   W (ret);
17264   return ret;
17265 }
17266
17267 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17268
17269 uword
17270 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17271 {
17272   u32 *mode = va_arg (*args, u32 *);
17273
17274   if (unformat (input, "lisp"))
17275     *mode = 0;
17276   else if (unformat (input, "vxlan"))
17277     *mode = 1;
17278   else
17279     return 0;
17280
17281   return 1;
17282 }
17283
17284 static int
17285 api_gpe_get_encap_mode (vat_main_t * vam)
17286 {
17287   vl_api_gpe_get_encap_mode_t *mp;
17288   int ret;
17289
17290   /* Construct the API message */
17291   M (GPE_GET_ENCAP_MODE, mp);
17292
17293   /* send it... */
17294   S (mp);
17295
17296   /* Wait for a reply... */
17297   W (ret);
17298   return ret;
17299 }
17300
17301 static int
17302 api_gpe_set_encap_mode (vat_main_t * vam)
17303 {
17304   unformat_input_t *input = vam->input;
17305   vl_api_gpe_set_encap_mode_t *mp;
17306   int ret;
17307   u32 mode = 0;
17308
17309   /* Parse args required to build the message */
17310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17311     {
17312       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17313         ;
17314       else
17315         break;
17316     }
17317
17318   /* Construct the API message */
17319   M (GPE_SET_ENCAP_MODE, mp);
17320
17321   mp->mode = mode;
17322
17323   /* send it... */
17324   S (mp);
17325
17326   /* Wait for a reply... */
17327   W (ret);
17328   return ret;
17329 }
17330
17331 static int
17332 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17333 {
17334   unformat_input_t *input = vam->input;
17335   vl_api_gpe_add_del_iface_t *mp;
17336   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17337   u32 dp_table = 0, vni = 0;
17338   int ret;
17339
17340   /* Parse args required to build the message */
17341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17342     {
17343       if (unformat (input, "up"))
17344         {
17345           action_set = 1;
17346           is_add = 1;
17347         }
17348       else if (unformat (input, "down"))
17349         {
17350           action_set = 1;
17351           is_add = 0;
17352         }
17353       else if (unformat (input, "table_id %d", &dp_table))
17354         {
17355           dp_table_set = 1;
17356         }
17357       else if (unformat (input, "bd_id %d", &dp_table))
17358         {
17359           dp_table_set = 1;
17360           is_l2 = 1;
17361         }
17362       else if (unformat (input, "vni %d", &vni))
17363         {
17364           vni_set = 1;
17365         }
17366       else
17367         break;
17368     }
17369
17370   if (action_set == 0)
17371     {
17372       errmsg ("Action not set");
17373       return -99;
17374     }
17375   if (dp_table_set == 0 || vni_set == 0)
17376     {
17377       errmsg ("vni and dp_table must be set");
17378       return -99;
17379     }
17380
17381   /* Construct the API message */
17382   M (GPE_ADD_DEL_IFACE, mp);
17383
17384   mp->is_add = is_add;
17385   mp->dp_table = clib_host_to_net_u32 (dp_table);
17386   mp->is_l2 = is_l2;
17387   mp->vni = clib_host_to_net_u32 (vni);
17388
17389   /* send it... */
17390   S (mp);
17391
17392   /* Wait for a reply... */
17393   W (ret);
17394   return ret;
17395 }
17396
17397 static int
17398 api_one_map_register_fallback_threshold (vat_main_t * vam)
17399 {
17400   unformat_input_t *input = vam->input;
17401   vl_api_one_map_register_fallback_threshold_t *mp;
17402   u32 value = 0;
17403   u8 is_set = 0;
17404   int ret;
17405
17406   /* Parse args required to build the message */
17407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17408     {
17409       if (unformat (input, "%u", &value))
17410         is_set = 1;
17411       else
17412         {
17413           clib_warning ("parse error '%U'", format_unformat_error, input);
17414           return -99;
17415         }
17416     }
17417
17418   if (!is_set)
17419     {
17420       errmsg ("fallback threshold value is missing!");
17421       return -99;
17422     }
17423
17424   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17425   mp->value = clib_host_to_net_u32 (value);
17426
17427   /* send it... */
17428   S (mp);
17429
17430   /* Wait for a reply... */
17431   W (ret);
17432   return ret;
17433 }
17434
17435 static int
17436 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17437 {
17438   vl_api_show_one_map_register_fallback_threshold_t *mp;
17439   int ret;
17440
17441   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17442
17443   /* send it... */
17444   S (mp);
17445
17446   /* Wait for a reply... */
17447   W (ret);
17448   return ret;
17449 }
17450
17451 uword
17452 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17453 {
17454   u32 *proto = va_arg (*args, u32 *);
17455
17456   if (unformat (input, "udp"))
17457     *proto = 1;
17458   else if (unformat (input, "api"))
17459     *proto = 2;
17460   else
17461     return 0;
17462
17463   return 1;
17464 }
17465
17466 static int
17467 api_one_set_transport_protocol (vat_main_t * vam)
17468 {
17469   unformat_input_t *input = vam->input;
17470   vl_api_one_set_transport_protocol_t *mp;
17471   u8 is_set = 0;
17472   u32 protocol = 0;
17473   int ret;
17474
17475   /* Parse args required to build the message */
17476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17477     {
17478       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17479         is_set = 1;
17480       else
17481         {
17482           clib_warning ("parse error '%U'", format_unformat_error, input);
17483           return -99;
17484         }
17485     }
17486
17487   if (!is_set)
17488     {
17489       errmsg ("Transport protocol missing!");
17490       return -99;
17491     }
17492
17493   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17494   mp->protocol = (u8) protocol;
17495
17496   /* send it... */
17497   S (mp);
17498
17499   /* Wait for a reply... */
17500   W (ret);
17501   return ret;
17502 }
17503
17504 static int
17505 api_one_get_transport_protocol (vat_main_t * vam)
17506 {
17507   vl_api_one_get_transport_protocol_t *mp;
17508   int ret;
17509
17510   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17511
17512   /* send it... */
17513   S (mp);
17514
17515   /* Wait for a reply... */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 static int
17521 api_one_map_register_set_ttl (vat_main_t * vam)
17522 {
17523   unformat_input_t *input = vam->input;
17524   vl_api_one_map_register_set_ttl_t *mp;
17525   u32 ttl = 0;
17526   u8 is_set = 0;
17527   int ret;
17528
17529   /* Parse args required to build the message */
17530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17531     {
17532       if (unformat (input, "%u", &ttl))
17533         is_set = 1;
17534       else
17535         {
17536           clib_warning ("parse error '%U'", format_unformat_error, input);
17537           return -99;
17538         }
17539     }
17540
17541   if (!is_set)
17542     {
17543       errmsg ("TTL value missing!");
17544       return -99;
17545     }
17546
17547   M (ONE_MAP_REGISTER_SET_TTL, mp);
17548   mp->ttl = clib_host_to_net_u32 (ttl);
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 static int
17559 api_show_one_map_register_ttl (vat_main_t * vam)
17560 {
17561   vl_api_show_one_map_register_ttl_t *mp;
17562   int ret;
17563
17564   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17565
17566   /* send it... */
17567   S (mp);
17568
17569   /* Wait for a reply... */
17570   W (ret);
17571   return ret;
17572 }
17573
17574 /**
17575  * Add/del map request itr rlocs from ONE control plane and updates
17576  *
17577  * @param vam vpp API test context
17578  * @return return code
17579  */
17580 static int
17581 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17582 {
17583   unformat_input_t *input = vam->input;
17584   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17585   u8 *locator_set_name = 0;
17586   u8 locator_set_name_set = 0;
17587   u8 is_add = 1;
17588   int ret;
17589
17590   /* Parse args required to build the message */
17591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17592     {
17593       if (unformat (input, "del"))
17594         {
17595           is_add = 0;
17596         }
17597       else if (unformat (input, "%_%v%_", &locator_set_name))
17598         {
17599           locator_set_name_set = 1;
17600         }
17601       else
17602         {
17603           clib_warning ("parse error '%U'", format_unformat_error, input);
17604           return -99;
17605         }
17606     }
17607
17608   if (is_add && !locator_set_name_set)
17609     {
17610       errmsg ("itr-rloc is not set!");
17611       return -99;
17612     }
17613
17614   if (is_add && vec_len (locator_set_name) > 64)
17615     {
17616       errmsg ("itr-rloc locator-set name too long");
17617       vec_free (locator_set_name);
17618       return -99;
17619     }
17620
17621   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17622   mp->is_add = is_add;
17623   if (is_add)
17624     {
17625       clib_memcpy (mp->locator_set_name, locator_set_name,
17626                    vec_len (locator_set_name));
17627     }
17628   else
17629     {
17630       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17631     }
17632   vec_free (locator_set_name);
17633
17634   /* send it... */
17635   S (mp);
17636
17637   /* Wait for a reply... */
17638   W (ret);
17639   return ret;
17640 }
17641
17642 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17643
17644 static int
17645 api_one_locator_dump (vat_main_t * vam)
17646 {
17647   unformat_input_t *input = vam->input;
17648   vl_api_one_locator_dump_t *mp;
17649   vl_api_control_ping_t *mp_ping;
17650   u8 is_index_set = 0, is_name_set = 0;
17651   u8 *ls_name = 0;
17652   u32 ls_index = ~0;
17653   int ret;
17654
17655   /* Parse args required to build the message */
17656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17657     {
17658       if (unformat (input, "ls_name %_%v%_", &ls_name))
17659         {
17660           is_name_set = 1;
17661         }
17662       else if (unformat (input, "ls_index %d", &ls_index))
17663         {
17664           is_index_set = 1;
17665         }
17666       else
17667         {
17668           errmsg ("parse error '%U'", format_unformat_error, input);
17669           return -99;
17670         }
17671     }
17672
17673   if (!is_index_set && !is_name_set)
17674     {
17675       errmsg ("error: expected one of index or name!");
17676       return -99;
17677     }
17678
17679   if (is_index_set && is_name_set)
17680     {
17681       errmsg ("error: only one param expected!");
17682       return -99;
17683     }
17684
17685   if (vec_len (ls_name) > 62)
17686     {
17687       errmsg ("error: locator set name too long!");
17688       return -99;
17689     }
17690
17691   if (!vam->json_output)
17692     {
17693       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17694     }
17695
17696   M (ONE_LOCATOR_DUMP, mp);
17697   mp->is_index_set = is_index_set;
17698
17699   if (is_index_set)
17700     mp->ls_index = clib_host_to_net_u32 (ls_index);
17701   else
17702     {
17703       vec_add1 (ls_name, 0);
17704       strncpy ((char *) mp->ls_name, (char *) ls_name,
17705                sizeof (mp->ls_name) - 1);
17706     }
17707
17708   /* send it... */
17709   S (mp);
17710
17711   /* Use a control ping for synchronization */
17712   MPING (CONTROL_PING, mp_ping);
17713   S (mp_ping);
17714
17715   /* Wait for a reply... */
17716   W (ret);
17717   return ret;
17718 }
17719
17720 #define api_lisp_locator_dump api_one_locator_dump
17721
17722 static int
17723 api_one_locator_set_dump (vat_main_t * vam)
17724 {
17725   vl_api_one_locator_set_dump_t *mp;
17726   vl_api_control_ping_t *mp_ping;
17727   unformat_input_t *input = vam->input;
17728   u8 filter = 0;
17729   int ret;
17730
17731   /* Parse args required to build the message */
17732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17733     {
17734       if (unformat (input, "local"))
17735         {
17736           filter = 1;
17737         }
17738       else if (unformat (input, "remote"))
17739         {
17740           filter = 2;
17741         }
17742       else
17743         {
17744           errmsg ("parse error '%U'", format_unformat_error, input);
17745           return -99;
17746         }
17747     }
17748
17749   if (!vam->json_output)
17750     {
17751       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17752     }
17753
17754   M (ONE_LOCATOR_SET_DUMP, mp);
17755
17756   mp->filter = filter;
17757
17758   /* send it... */
17759   S (mp);
17760
17761   /* Use a control ping for synchronization */
17762   MPING (CONTROL_PING, mp_ping);
17763   S (mp_ping);
17764
17765   /* Wait for a reply... */
17766   W (ret);
17767   return ret;
17768 }
17769
17770 #define api_lisp_locator_set_dump api_one_locator_set_dump
17771
17772 static int
17773 api_one_eid_table_map_dump (vat_main_t * vam)
17774 {
17775   u8 is_l2 = 0;
17776   u8 mode_set = 0;
17777   unformat_input_t *input = vam->input;
17778   vl_api_one_eid_table_map_dump_t *mp;
17779   vl_api_control_ping_t *mp_ping;
17780   int ret;
17781
17782   /* Parse args required to build the message */
17783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17784     {
17785       if (unformat (input, "l2"))
17786         {
17787           is_l2 = 1;
17788           mode_set = 1;
17789         }
17790       else if (unformat (input, "l3"))
17791         {
17792           is_l2 = 0;
17793           mode_set = 1;
17794         }
17795       else
17796         {
17797           errmsg ("parse error '%U'", format_unformat_error, input);
17798           return -99;
17799         }
17800     }
17801
17802   if (!mode_set)
17803     {
17804       errmsg ("expected one of 'l2' or 'l3' parameter!");
17805       return -99;
17806     }
17807
17808   if (!vam->json_output)
17809     {
17810       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17811     }
17812
17813   M (ONE_EID_TABLE_MAP_DUMP, mp);
17814   mp->is_l2 = is_l2;
17815
17816   /* send it... */
17817   S (mp);
17818
17819   /* Use a control ping for synchronization */
17820   MPING (CONTROL_PING, mp_ping);
17821   S (mp_ping);
17822
17823   /* Wait for a reply... */
17824   W (ret);
17825   return ret;
17826 }
17827
17828 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17829
17830 static int
17831 api_one_eid_table_vni_dump (vat_main_t * vam)
17832 {
17833   vl_api_one_eid_table_vni_dump_t *mp;
17834   vl_api_control_ping_t *mp_ping;
17835   int ret;
17836
17837   if (!vam->json_output)
17838     {
17839       print (vam->ofp, "VNI");
17840     }
17841
17842   M (ONE_EID_TABLE_VNI_DUMP, mp);
17843
17844   /* send it... */
17845   S (mp);
17846
17847   /* Use a control ping for synchronization */
17848   MPING (CONTROL_PING, mp_ping);
17849   S (mp_ping);
17850
17851   /* Wait for a reply... */
17852   W (ret);
17853   return ret;
17854 }
17855
17856 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17857
17858 static int
17859 api_one_eid_table_dump (vat_main_t * vam)
17860 {
17861   unformat_input_t *i = vam->input;
17862   vl_api_one_eid_table_dump_t *mp;
17863   vl_api_control_ping_t *mp_ping;
17864   struct in_addr ip4;
17865   struct in6_addr ip6;
17866   u8 mac[6];
17867   u8 eid_type = ~0, eid_set = 0;
17868   u32 prefix_length = ~0, t, vni = 0;
17869   u8 filter = 0;
17870   int ret;
17871   lisp_nsh_api_t nsh;
17872
17873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17876         {
17877           eid_set = 1;
17878           eid_type = 0;
17879           prefix_length = t;
17880         }
17881       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17882         {
17883           eid_set = 1;
17884           eid_type = 1;
17885           prefix_length = t;
17886         }
17887       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17888         {
17889           eid_set = 1;
17890           eid_type = 2;
17891         }
17892       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17893         {
17894           eid_set = 1;
17895           eid_type = 3;
17896         }
17897       else if (unformat (i, "vni %d", &t))
17898         {
17899           vni = t;
17900         }
17901       else if (unformat (i, "local"))
17902         {
17903           filter = 1;
17904         }
17905       else if (unformat (i, "remote"))
17906         {
17907           filter = 2;
17908         }
17909       else
17910         {
17911           errmsg ("parse error '%U'", format_unformat_error, i);
17912           return -99;
17913         }
17914     }
17915
17916   if (!vam->json_output)
17917     {
17918       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17919              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17920     }
17921
17922   M (ONE_EID_TABLE_DUMP, mp);
17923
17924   mp->filter = filter;
17925   if (eid_set)
17926     {
17927       mp->eid_set = 1;
17928       mp->vni = htonl (vni);
17929       mp->eid_type = eid_type;
17930       switch (eid_type)
17931         {
17932         case 0:
17933           mp->prefix_length = prefix_length;
17934           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17935           break;
17936         case 1:
17937           mp->prefix_length = prefix_length;
17938           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17939           break;
17940         case 2:
17941           clib_memcpy (mp->eid, mac, sizeof (mac));
17942           break;
17943         case 3:
17944           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17945           break;
17946         default:
17947           errmsg ("unknown EID type %d!", eid_type);
17948           return -99;
17949         }
17950     }
17951
17952   /* send it... */
17953   S (mp);
17954
17955   /* Use a control ping for synchronization */
17956   MPING (CONTROL_PING, mp_ping);
17957   S (mp_ping);
17958
17959   /* Wait for a reply... */
17960   W (ret);
17961   return ret;
17962 }
17963
17964 #define api_lisp_eid_table_dump api_one_eid_table_dump
17965
17966 static int
17967 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17968 {
17969   unformat_input_t *i = vam->input;
17970   vl_api_gpe_fwd_entries_get_t *mp;
17971   u8 vni_set = 0;
17972   u32 vni = ~0;
17973   int ret;
17974
17975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17976     {
17977       if (unformat (i, "vni %d", &vni))
17978         {
17979           vni_set = 1;
17980         }
17981       else
17982         {
17983           errmsg ("parse error '%U'", format_unformat_error, i);
17984           return -99;
17985         }
17986     }
17987
17988   if (!vni_set)
17989     {
17990       errmsg ("vni not set!");
17991       return -99;
17992     }
17993
17994   if (!vam->json_output)
17995     {
17996       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17997              "leid", "reid");
17998     }
17999
18000   M (GPE_FWD_ENTRIES_GET, mp);
18001   mp->vni = clib_host_to_net_u32 (vni);
18002
18003   /* send it... */
18004   S (mp);
18005
18006   /* Wait for a reply... */
18007   W (ret);
18008   return ret;
18009 }
18010
18011 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18012 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18013 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18014 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18015 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18016 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18017 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18018 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18019
18020 static int
18021 api_one_adjacencies_get (vat_main_t * vam)
18022 {
18023   unformat_input_t *i = vam->input;
18024   vl_api_one_adjacencies_get_t *mp;
18025   u8 vni_set = 0;
18026   u32 vni = ~0;
18027   int ret;
18028
18029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18030     {
18031       if (unformat (i, "vni %d", &vni))
18032         {
18033           vni_set = 1;
18034         }
18035       else
18036         {
18037           errmsg ("parse error '%U'", format_unformat_error, i);
18038           return -99;
18039         }
18040     }
18041
18042   if (!vni_set)
18043     {
18044       errmsg ("vni not set!");
18045       return -99;
18046     }
18047
18048   if (!vam->json_output)
18049     {
18050       print (vam->ofp, "%s %40s", "leid", "reid");
18051     }
18052
18053   M (ONE_ADJACENCIES_GET, mp);
18054   mp->vni = clib_host_to_net_u32 (vni);
18055
18056   /* send it... */
18057   S (mp);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 #define api_lisp_adjacencies_get api_one_adjacencies_get
18065
18066 static int
18067 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18068 {
18069   unformat_input_t *i = vam->input;
18070   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18071   int ret;
18072   u8 ip_family_set = 0, is_ip4 = 1;
18073
18074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18075     {
18076       if (unformat (i, "ip4"))
18077         {
18078           ip_family_set = 1;
18079           is_ip4 = 1;
18080         }
18081       else if (unformat (i, "ip6"))
18082         {
18083           ip_family_set = 1;
18084           is_ip4 = 0;
18085         }
18086       else
18087         {
18088           errmsg ("parse error '%U'", format_unformat_error, i);
18089           return -99;
18090         }
18091     }
18092
18093   if (!ip_family_set)
18094     {
18095       errmsg ("ip family not set!");
18096       return -99;
18097     }
18098
18099   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18100   mp->is_ip4 = is_ip4;
18101
18102   /* send it... */
18103   S (mp);
18104
18105   /* Wait for a reply... */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 static int
18111 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18112 {
18113   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18114   int ret;
18115
18116   if (!vam->json_output)
18117     {
18118       print (vam->ofp, "VNIs");
18119     }
18120
18121   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18122
18123   /* send it... */
18124   S (mp);
18125
18126   /* Wait for a reply... */
18127   W (ret);
18128   return ret;
18129 }
18130
18131 static int
18132 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18133 {
18134   unformat_input_t *i = vam->input;
18135   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18136   int ret = 0;
18137   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18138   struct in_addr ip4;
18139   struct in6_addr ip6;
18140   u32 table_id = 0, nh_sw_if_index = ~0;
18141
18142   memset (&ip4, 0, sizeof (ip4));
18143   memset (&ip6, 0, sizeof (ip6));
18144
18145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18146     {
18147       if (unformat (i, "del"))
18148         is_add = 0;
18149       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18150                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18151         {
18152           ip_set = 1;
18153           is_ip4 = 1;
18154         }
18155       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18156                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18157         {
18158           ip_set = 1;
18159           is_ip4 = 0;
18160         }
18161       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18162         {
18163           ip_set = 1;
18164           is_ip4 = 1;
18165           nh_sw_if_index = ~0;
18166         }
18167       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18168         {
18169           ip_set = 1;
18170           is_ip4 = 0;
18171           nh_sw_if_index = ~0;
18172         }
18173       else if (unformat (i, "table %d", &table_id))
18174         ;
18175       else
18176         {
18177           errmsg ("parse error '%U'", format_unformat_error, i);
18178           return -99;
18179         }
18180     }
18181
18182   if (!ip_set)
18183     {
18184       errmsg ("nh addr not set!");
18185       return -99;
18186     }
18187
18188   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18189   mp->is_add = is_add;
18190   mp->table_id = clib_host_to_net_u32 (table_id);
18191   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18192   mp->is_ip4 = is_ip4;
18193   if (is_ip4)
18194     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18195   else
18196     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18197
18198   /* send it... */
18199   S (mp);
18200
18201   /* Wait for a reply... */
18202   W (ret);
18203   return ret;
18204 }
18205
18206 static int
18207 api_one_map_server_dump (vat_main_t * vam)
18208 {
18209   vl_api_one_map_server_dump_t *mp;
18210   vl_api_control_ping_t *mp_ping;
18211   int ret;
18212
18213   if (!vam->json_output)
18214     {
18215       print (vam->ofp, "%=20s", "Map server");
18216     }
18217
18218   M (ONE_MAP_SERVER_DUMP, mp);
18219   /* send it... */
18220   S (mp);
18221
18222   /* Use a control ping for synchronization */
18223   MPING (CONTROL_PING, mp_ping);
18224   S (mp_ping);
18225
18226   /* Wait for a reply... */
18227   W (ret);
18228   return ret;
18229 }
18230
18231 #define api_lisp_map_server_dump api_one_map_server_dump
18232
18233 static int
18234 api_one_map_resolver_dump (vat_main_t * vam)
18235 {
18236   vl_api_one_map_resolver_dump_t *mp;
18237   vl_api_control_ping_t *mp_ping;
18238   int ret;
18239
18240   if (!vam->json_output)
18241     {
18242       print (vam->ofp, "%=20s", "Map resolver");
18243     }
18244
18245   M (ONE_MAP_RESOLVER_DUMP, mp);
18246   /* send it... */
18247   S (mp);
18248
18249   /* Use a control ping for synchronization */
18250   MPING (CONTROL_PING, mp_ping);
18251   S (mp_ping);
18252
18253   /* Wait for a reply... */
18254   W (ret);
18255   return ret;
18256 }
18257
18258 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18259
18260 static int
18261 api_one_stats_flush (vat_main_t * vam)
18262 {
18263   vl_api_one_stats_flush_t *mp;
18264   int ret = 0;
18265
18266   M (ONE_STATS_FLUSH, mp);
18267   S (mp);
18268   W (ret);
18269   return ret;
18270 }
18271
18272 static int
18273 api_one_stats_dump (vat_main_t * vam)
18274 {
18275   vl_api_one_stats_dump_t *mp;
18276   vl_api_control_ping_t *mp_ping;
18277   int ret;
18278
18279   M (ONE_STATS_DUMP, mp);
18280   /* send it... */
18281   S (mp);
18282
18283   /* Use a control ping for synchronization */
18284   MPING (CONTROL_PING, mp_ping);
18285   S (mp_ping);
18286
18287   /* Wait for a reply... */
18288   W (ret);
18289   return ret;
18290 }
18291
18292 static int
18293 api_show_one_status (vat_main_t * vam)
18294 {
18295   vl_api_show_one_status_t *mp;
18296   int ret;
18297
18298   if (!vam->json_output)
18299     {
18300       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18301     }
18302
18303   M (SHOW_ONE_STATUS, mp);
18304   /* send it... */
18305   S (mp);
18306   /* Wait for a reply... */
18307   W (ret);
18308   return ret;
18309 }
18310
18311 #define api_show_lisp_status api_show_one_status
18312
18313 static int
18314 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18315 {
18316   vl_api_gpe_fwd_entry_path_dump_t *mp;
18317   vl_api_control_ping_t *mp_ping;
18318   unformat_input_t *i = vam->input;
18319   u32 fwd_entry_index = ~0;
18320   int ret;
18321
18322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18323     {
18324       if (unformat (i, "index %d", &fwd_entry_index))
18325         ;
18326       else
18327         break;
18328     }
18329
18330   if (~0 == fwd_entry_index)
18331     {
18332       errmsg ("no index specified!");
18333       return -99;
18334     }
18335
18336   if (!vam->json_output)
18337     {
18338       print (vam->ofp, "first line");
18339     }
18340
18341   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18342
18343   /* send it... */
18344   S (mp);
18345   /* Use a control ping for synchronization */
18346   MPING (CONTROL_PING, mp_ping);
18347   S (mp_ping);
18348
18349   /* Wait for a reply... */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18356 {
18357   vl_api_one_get_map_request_itr_rlocs_t *mp;
18358   int ret;
18359
18360   if (!vam->json_output)
18361     {
18362       print (vam->ofp, "%=20s", "itr-rlocs:");
18363     }
18364
18365   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18366   /* send it... */
18367   S (mp);
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18374
18375 static int
18376 api_af_packet_create (vat_main_t * vam)
18377 {
18378   unformat_input_t *i = vam->input;
18379   vl_api_af_packet_create_t *mp;
18380   u8 *host_if_name = 0;
18381   u8 hw_addr[6];
18382   u8 random_hw_addr = 1;
18383   int ret;
18384
18385   memset (hw_addr, 0, sizeof (hw_addr));
18386
18387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (i, "name %s", &host_if_name))
18390         vec_add1 (host_if_name, 0);
18391       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18392         random_hw_addr = 0;
18393       else
18394         break;
18395     }
18396
18397   if (!vec_len (host_if_name))
18398     {
18399       errmsg ("host-interface name must be specified");
18400       return -99;
18401     }
18402
18403   if (vec_len (host_if_name) > 64)
18404     {
18405       errmsg ("host-interface name too long");
18406       return -99;
18407     }
18408
18409   M (AF_PACKET_CREATE, mp);
18410
18411   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18412   clib_memcpy (mp->hw_addr, hw_addr, 6);
18413   mp->use_random_hw_addr = random_hw_addr;
18414   vec_free (host_if_name);
18415
18416   S (mp);
18417
18418   /* *INDENT-OFF* */
18419   W2 (ret,
18420       ({
18421         if (ret == 0)
18422           fprintf (vam->ofp ? vam->ofp : stderr,
18423                    " new sw_if_index = %d\n", vam->sw_if_index);
18424       }));
18425   /* *INDENT-ON* */
18426   return ret;
18427 }
18428
18429 static int
18430 api_af_packet_delete (vat_main_t * vam)
18431 {
18432   unformat_input_t *i = vam->input;
18433   vl_api_af_packet_delete_t *mp;
18434   u8 *host_if_name = 0;
18435   int ret;
18436
18437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18438     {
18439       if (unformat (i, "name %s", &host_if_name))
18440         vec_add1 (host_if_name, 0);
18441       else
18442         break;
18443     }
18444
18445   if (!vec_len (host_if_name))
18446     {
18447       errmsg ("host-interface name must be specified");
18448       return -99;
18449     }
18450
18451   if (vec_len (host_if_name) > 64)
18452     {
18453       errmsg ("host-interface name too long");
18454       return -99;
18455     }
18456
18457   M (AF_PACKET_DELETE, mp);
18458
18459   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18460   vec_free (host_if_name);
18461
18462   S (mp);
18463   W (ret);
18464   return ret;
18465 }
18466
18467 static int
18468 api_policer_add_del (vat_main_t * vam)
18469 {
18470   unformat_input_t *i = vam->input;
18471   vl_api_policer_add_del_t *mp;
18472   u8 is_add = 1;
18473   u8 *name = 0;
18474   u32 cir = 0;
18475   u32 eir = 0;
18476   u64 cb = 0;
18477   u64 eb = 0;
18478   u8 rate_type = 0;
18479   u8 round_type = 0;
18480   u8 type = 0;
18481   u8 color_aware = 0;
18482   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18483   int ret;
18484
18485   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18486   conform_action.dscp = 0;
18487   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18488   exceed_action.dscp = 0;
18489   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18490   violate_action.dscp = 0;
18491
18492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (i, "del"))
18495         is_add = 0;
18496       else if (unformat (i, "name %s", &name))
18497         vec_add1 (name, 0);
18498       else if (unformat (i, "cir %u", &cir))
18499         ;
18500       else if (unformat (i, "eir %u", &eir))
18501         ;
18502       else if (unformat (i, "cb %u", &cb))
18503         ;
18504       else if (unformat (i, "eb %u", &eb))
18505         ;
18506       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18507                          &rate_type))
18508         ;
18509       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18510                          &round_type))
18511         ;
18512       else if (unformat (i, "type %U", unformat_policer_type, &type))
18513         ;
18514       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18515                          &conform_action))
18516         ;
18517       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18518                          &exceed_action))
18519         ;
18520       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18521                          &violate_action))
18522         ;
18523       else if (unformat (i, "color-aware"))
18524         color_aware = 1;
18525       else
18526         break;
18527     }
18528
18529   if (!vec_len (name))
18530     {
18531       errmsg ("policer name must be specified");
18532       return -99;
18533     }
18534
18535   if (vec_len (name) > 64)
18536     {
18537       errmsg ("policer name too long");
18538       return -99;
18539     }
18540
18541   M (POLICER_ADD_DEL, mp);
18542
18543   clib_memcpy (mp->name, name, vec_len (name));
18544   vec_free (name);
18545   mp->is_add = is_add;
18546   mp->cir = ntohl (cir);
18547   mp->eir = ntohl (eir);
18548   mp->cb = clib_net_to_host_u64 (cb);
18549   mp->eb = clib_net_to_host_u64 (eb);
18550   mp->rate_type = rate_type;
18551   mp->round_type = round_type;
18552   mp->type = type;
18553   mp->conform_action_type = conform_action.action_type;
18554   mp->conform_dscp = conform_action.dscp;
18555   mp->exceed_action_type = exceed_action.action_type;
18556   mp->exceed_dscp = exceed_action.dscp;
18557   mp->violate_action_type = violate_action.action_type;
18558   mp->violate_dscp = violate_action.dscp;
18559   mp->color_aware = color_aware;
18560
18561   S (mp);
18562   W (ret);
18563   return ret;
18564 }
18565
18566 static int
18567 api_policer_dump (vat_main_t * vam)
18568 {
18569   unformat_input_t *i = vam->input;
18570   vl_api_policer_dump_t *mp;
18571   vl_api_control_ping_t *mp_ping;
18572   u8 *match_name = 0;
18573   u8 match_name_valid = 0;
18574   int ret;
18575
18576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18577     {
18578       if (unformat (i, "name %s", &match_name))
18579         {
18580           vec_add1 (match_name, 0);
18581           match_name_valid = 1;
18582         }
18583       else
18584         break;
18585     }
18586
18587   M (POLICER_DUMP, mp);
18588   mp->match_name_valid = match_name_valid;
18589   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18590   vec_free (match_name);
18591   /* send it... */
18592   S (mp);
18593
18594   /* Use a control ping for synchronization */
18595   MPING (CONTROL_PING, mp_ping);
18596   S (mp_ping);
18597
18598   /* Wait for a reply... */
18599   W (ret);
18600   return ret;
18601 }
18602
18603 static int
18604 api_policer_classify_set_interface (vat_main_t * vam)
18605 {
18606   unformat_input_t *i = vam->input;
18607   vl_api_policer_classify_set_interface_t *mp;
18608   u32 sw_if_index;
18609   int sw_if_index_set;
18610   u32 ip4_table_index = ~0;
18611   u32 ip6_table_index = ~0;
18612   u32 l2_table_index = ~0;
18613   u8 is_add = 1;
18614   int ret;
18615
18616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18617     {
18618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18619         sw_if_index_set = 1;
18620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18621         sw_if_index_set = 1;
18622       else if (unformat (i, "del"))
18623         is_add = 0;
18624       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18625         ;
18626       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18627         ;
18628       else if (unformat (i, "l2-table %d", &l2_table_index))
18629         ;
18630       else
18631         {
18632           clib_warning ("parse error '%U'", format_unformat_error, i);
18633           return -99;
18634         }
18635     }
18636
18637   if (sw_if_index_set == 0)
18638     {
18639       errmsg ("missing interface name or sw_if_index");
18640       return -99;
18641     }
18642
18643   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18644
18645   mp->sw_if_index = ntohl (sw_if_index);
18646   mp->ip4_table_index = ntohl (ip4_table_index);
18647   mp->ip6_table_index = ntohl (ip6_table_index);
18648   mp->l2_table_index = ntohl (l2_table_index);
18649   mp->is_add = is_add;
18650
18651   S (mp);
18652   W (ret);
18653   return ret;
18654 }
18655
18656 static int
18657 api_policer_classify_dump (vat_main_t * vam)
18658 {
18659   unformat_input_t *i = vam->input;
18660   vl_api_policer_classify_dump_t *mp;
18661   vl_api_control_ping_t *mp_ping;
18662   u8 type = POLICER_CLASSIFY_N_TABLES;
18663   int ret;
18664
18665   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18666     ;
18667   else
18668     {
18669       errmsg ("classify table type must be specified");
18670       return -99;
18671     }
18672
18673   if (!vam->json_output)
18674     {
18675       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18676     }
18677
18678   M (POLICER_CLASSIFY_DUMP, mp);
18679   mp->type = type;
18680   /* send it... */
18681   S (mp);
18682
18683   /* Use a control ping for synchronization */
18684   MPING (CONTROL_PING, mp_ping);
18685   S (mp_ping);
18686
18687   /* Wait for a reply... */
18688   W (ret);
18689   return ret;
18690 }
18691
18692 static int
18693 api_netmap_create (vat_main_t * vam)
18694 {
18695   unformat_input_t *i = vam->input;
18696   vl_api_netmap_create_t *mp;
18697   u8 *if_name = 0;
18698   u8 hw_addr[6];
18699   u8 random_hw_addr = 1;
18700   u8 is_pipe = 0;
18701   u8 is_master = 0;
18702   int ret;
18703
18704   memset (hw_addr, 0, sizeof (hw_addr));
18705
18706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18707     {
18708       if (unformat (i, "name %s", &if_name))
18709         vec_add1 (if_name, 0);
18710       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18711         random_hw_addr = 0;
18712       else if (unformat (i, "pipe"))
18713         is_pipe = 1;
18714       else if (unformat (i, "master"))
18715         is_master = 1;
18716       else if (unformat (i, "slave"))
18717         is_master = 0;
18718       else
18719         break;
18720     }
18721
18722   if (!vec_len (if_name))
18723     {
18724       errmsg ("interface name must be specified");
18725       return -99;
18726     }
18727
18728   if (vec_len (if_name) > 64)
18729     {
18730       errmsg ("interface name too long");
18731       return -99;
18732     }
18733
18734   M (NETMAP_CREATE, mp);
18735
18736   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18737   clib_memcpy (mp->hw_addr, hw_addr, 6);
18738   mp->use_random_hw_addr = random_hw_addr;
18739   mp->is_pipe = is_pipe;
18740   mp->is_master = is_master;
18741   vec_free (if_name);
18742
18743   S (mp);
18744   W (ret);
18745   return ret;
18746 }
18747
18748 static int
18749 api_netmap_delete (vat_main_t * vam)
18750 {
18751   unformat_input_t *i = vam->input;
18752   vl_api_netmap_delete_t *mp;
18753   u8 *if_name = 0;
18754   int ret;
18755
18756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18757     {
18758       if (unformat (i, "name %s", &if_name))
18759         vec_add1 (if_name, 0);
18760       else
18761         break;
18762     }
18763
18764   if (!vec_len (if_name))
18765     {
18766       errmsg ("interface name must be specified");
18767       return -99;
18768     }
18769
18770   if (vec_len (if_name) > 64)
18771     {
18772       errmsg ("interface name too long");
18773       return -99;
18774     }
18775
18776   M (NETMAP_DELETE, mp);
18777
18778   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18779   vec_free (if_name);
18780
18781   S (mp);
18782   W (ret);
18783   return ret;
18784 }
18785
18786 static void
18787 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18788 {
18789   if (fp->afi == IP46_TYPE_IP6)
18790     print (vam->ofp,
18791            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18792            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18793            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18794            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18795            format_ip6_address, fp->next_hop);
18796   else if (fp->afi == IP46_TYPE_IP4)
18797     print (vam->ofp,
18798            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18799            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18800            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18801            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18802            format_ip4_address, fp->next_hop);
18803 }
18804
18805 static void
18806 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18807                                  vl_api_fib_path2_t * fp)
18808 {
18809   struct in_addr ip4;
18810   struct in6_addr ip6;
18811
18812   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18813   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18814   vat_json_object_add_uint (node, "is_local", fp->is_local);
18815   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18816   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18817   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18818   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18819   if (fp->afi == IP46_TYPE_IP4)
18820     {
18821       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18822       vat_json_object_add_ip4 (node, "next_hop", ip4);
18823     }
18824   else if (fp->afi == IP46_TYPE_IP6)
18825     {
18826       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18827       vat_json_object_add_ip6 (node, "next_hop", ip6);
18828     }
18829 }
18830
18831 static void
18832 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18833 {
18834   vat_main_t *vam = &vat_main;
18835   int count = ntohl (mp->mt_count);
18836   vl_api_fib_path2_t *fp;
18837   i32 i;
18838
18839   print (vam->ofp, "[%d]: sw_if_index %d via:",
18840          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18841   fp = mp->mt_paths;
18842   for (i = 0; i < count; i++)
18843     {
18844       vl_api_mpls_fib_path_print (vam, fp);
18845       fp++;
18846     }
18847
18848   print (vam->ofp, "");
18849 }
18850
18851 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18852 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18853
18854 static void
18855 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18856 {
18857   vat_main_t *vam = &vat_main;
18858   vat_json_node_t *node = NULL;
18859   int count = ntohl (mp->mt_count);
18860   vl_api_fib_path2_t *fp;
18861   i32 i;
18862
18863   if (VAT_JSON_ARRAY != vam->json_tree.type)
18864     {
18865       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18866       vat_json_init_array (&vam->json_tree);
18867     }
18868   node = vat_json_array_add (&vam->json_tree);
18869
18870   vat_json_init_object (node);
18871   vat_json_object_add_uint (node, "tunnel_index",
18872                             ntohl (mp->mt_tunnel_index));
18873   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18874
18875   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18876
18877   fp = mp->mt_paths;
18878   for (i = 0; i < count; i++)
18879     {
18880       vl_api_mpls_fib_path_json_print (node, fp);
18881       fp++;
18882     }
18883 }
18884
18885 static int
18886 api_mpls_tunnel_dump (vat_main_t * vam)
18887 {
18888   vl_api_mpls_tunnel_dump_t *mp;
18889   vl_api_control_ping_t *mp_ping;
18890   i32 index = -1;
18891   int ret;
18892
18893   /* Parse args required to build the message */
18894   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18895     {
18896       if (!unformat (vam->input, "tunnel_index %d", &index))
18897         {
18898           index = -1;
18899           break;
18900         }
18901     }
18902
18903   print (vam->ofp, "  tunnel_index %d", index);
18904
18905   M (MPLS_TUNNEL_DUMP, mp);
18906   mp->tunnel_index = htonl (index);
18907   S (mp);
18908
18909   /* Use a control ping for synchronization */
18910   MPING (CONTROL_PING, mp_ping);
18911   S (mp_ping);
18912
18913   W (ret);
18914   return ret;
18915 }
18916
18917 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18918 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18919
18920
18921 static void
18922 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18923 {
18924   vat_main_t *vam = &vat_main;
18925   int count = ntohl (mp->count);
18926   vl_api_fib_path2_t *fp;
18927   int i;
18928
18929   print (vam->ofp,
18930          "table-id %d, label %u, ess_bit %u",
18931          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18932   fp = mp->path;
18933   for (i = 0; i < count; i++)
18934     {
18935       vl_api_mpls_fib_path_print (vam, fp);
18936       fp++;
18937     }
18938 }
18939
18940 static void vl_api_mpls_fib_details_t_handler_json
18941   (vl_api_mpls_fib_details_t * mp)
18942 {
18943   vat_main_t *vam = &vat_main;
18944   int count = ntohl (mp->count);
18945   vat_json_node_t *node = NULL;
18946   vl_api_fib_path2_t *fp;
18947   int i;
18948
18949   if (VAT_JSON_ARRAY != vam->json_tree.type)
18950     {
18951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18952       vat_json_init_array (&vam->json_tree);
18953     }
18954   node = vat_json_array_add (&vam->json_tree);
18955
18956   vat_json_init_object (node);
18957   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18958   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18959   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18960   vat_json_object_add_uint (node, "path_count", count);
18961   fp = mp->path;
18962   for (i = 0; i < count; i++)
18963     {
18964       vl_api_mpls_fib_path_json_print (node, fp);
18965       fp++;
18966     }
18967 }
18968
18969 static int
18970 api_mpls_fib_dump (vat_main_t * vam)
18971 {
18972   vl_api_mpls_fib_dump_t *mp;
18973   vl_api_control_ping_t *mp_ping;
18974   int ret;
18975
18976   M (MPLS_FIB_DUMP, mp);
18977   S (mp);
18978
18979   /* Use a control ping for synchronization */
18980   MPING (CONTROL_PING, mp_ping);
18981   S (mp_ping);
18982
18983   W (ret);
18984   return ret;
18985 }
18986
18987 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18988 #define vl_api_ip_fib_details_t_print vl_noop_handler
18989
18990 static void
18991 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18992 {
18993   vat_main_t *vam = &vat_main;
18994   int count = ntohl (mp->count);
18995   vl_api_fib_path_t *fp;
18996   int i;
18997
18998   print (vam->ofp,
18999          "table-id %d, prefix %U/%d",
19000          ntohl (mp->table_id), format_ip4_address, mp->address,
19001          mp->address_length);
19002   fp = mp->path;
19003   for (i = 0; i < count; i++)
19004     {
19005       if (fp->afi == IP46_TYPE_IP6)
19006         print (vam->ofp,
19007                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19008                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19009                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19010                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19011                format_ip6_address, fp->next_hop);
19012       else if (fp->afi == IP46_TYPE_IP4)
19013         print (vam->ofp,
19014                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19015                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19016                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19017                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19018                format_ip4_address, fp->next_hop);
19019       fp++;
19020     }
19021 }
19022
19023 static void vl_api_ip_fib_details_t_handler_json
19024   (vl_api_ip_fib_details_t * mp)
19025 {
19026   vat_main_t *vam = &vat_main;
19027   int count = ntohl (mp->count);
19028   vat_json_node_t *node = NULL;
19029   struct in_addr ip4;
19030   struct in6_addr ip6;
19031   vl_api_fib_path_t *fp;
19032   int i;
19033
19034   if (VAT_JSON_ARRAY != vam->json_tree.type)
19035     {
19036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19037       vat_json_init_array (&vam->json_tree);
19038     }
19039   node = vat_json_array_add (&vam->json_tree);
19040
19041   vat_json_init_object (node);
19042   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19043   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19044   vat_json_object_add_ip4 (node, "prefix", ip4);
19045   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19046   vat_json_object_add_uint (node, "path_count", count);
19047   fp = mp->path;
19048   for (i = 0; i < count; i++)
19049     {
19050       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19051       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19052       vat_json_object_add_uint (node, "is_local", fp->is_local);
19053       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19054       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19055       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19056       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19057       if (fp->afi == IP46_TYPE_IP4)
19058         {
19059           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19060           vat_json_object_add_ip4 (node, "next_hop", ip4);
19061         }
19062       else if (fp->afi == IP46_TYPE_IP6)
19063         {
19064           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19065           vat_json_object_add_ip6 (node, "next_hop", ip6);
19066         }
19067     }
19068 }
19069
19070 static int
19071 api_ip_fib_dump (vat_main_t * vam)
19072 {
19073   vl_api_ip_fib_dump_t *mp;
19074   vl_api_control_ping_t *mp_ping;
19075   int ret;
19076
19077   M (IP_FIB_DUMP, mp);
19078   S (mp);
19079
19080   /* Use a control ping for synchronization */
19081   MPING (CONTROL_PING, mp_ping);
19082   S (mp_ping);
19083
19084   W (ret);
19085   return ret;
19086 }
19087
19088 static int
19089 api_ip_mfib_dump (vat_main_t * vam)
19090 {
19091   vl_api_ip_mfib_dump_t *mp;
19092   vl_api_control_ping_t *mp_ping;
19093   int ret;
19094
19095   M (IP_MFIB_DUMP, mp);
19096   S (mp);
19097
19098   /* Use a control ping for synchronization */
19099   MPING (CONTROL_PING, mp_ping);
19100   S (mp_ping);
19101
19102   W (ret);
19103   return ret;
19104 }
19105
19106 static void vl_api_ip_neighbor_details_t_handler
19107   (vl_api_ip_neighbor_details_t * mp)
19108 {
19109   vat_main_t *vam = &vat_main;
19110
19111   print (vam->ofp, "%c %U %U",
19112          (mp->is_static) ? 'S' : 'D',
19113          format_ethernet_address, &mp->mac_address,
19114          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19115          &mp->ip_address);
19116 }
19117
19118 static void vl_api_ip_neighbor_details_t_handler_json
19119   (vl_api_ip_neighbor_details_t * mp)
19120 {
19121
19122   vat_main_t *vam = &vat_main;
19123   vat_json_node_t *node;
19124   struct in_addr ip4;
19125   struct in6_addr ip6;
19126
19127   if (VAT_JSON_ARRAY != vam->json_tree.type)
19128     {
19129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19130       vat_json_init_array (&vam->json_tree);
19131     }
19132   node = vat_json_array_add (&vam->json_tree);
19133
19134   vat_json_init_object (node);
19135   vat_json_object_add_string_copy (node, "flag",
19136                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19137                                    "dynamic");
19138
19139   vat_json_object_add_string_copy (node, "link_layer",
19140                                    format (0, "%U", format_ethernet_address,
19141                                            &mp->mac_address));
19142
19143   if (mp->is_ipv6)
19144     {
19145       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19146       vat_json_object_add_ip6 (node, "ip_address", ip6);
19147     }
19148   else
19149     {
19150       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19151       vat_json_object_add_ip4 (node, "ip_address", ip4);
19152     }
19153 }
19154
19155 static int
19156 api_ip_neighbor_dump (vat_main_t * vam)
19157 {
19158   unformat_input_t *i = vam->input;
19159   vl_api_ip_neighbor_dump_t *mp;
19160   vl_api_control_ping_t *mp_ping;
19161   u8 is_ipv6 = 0;
19162   u32 sw_if_index = ~0;
19163   int ret;
19164
19165   /* Parse args required to build the message */
19166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19167     {
19168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19169         ;
19170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19171         ;
19172       else if (unformat (i, "ip6"))
19173         is_ipv6 = 1;
19174       else
19175         break;
19176     }
19177
19178   if (sw_if_index == ~0)
19179     {
19180       errmsg ("missing interface name or sw_if_index");
19181       return -99;
19182     }
19183
19184   M (IP_NEIGHBOR_DUMP, mp);
19185   mp->is_ipv6 = (u8) is_ipv6;
19186   mp->sw_if_index = ntohl (sw_if_index);
19187   S (mp);
19188
19189   /* Use a control ping for synchronization */
19190   MPING (CONTROL_PING, mp_ping);
19191   S (mp_ping);
19192
19193   W (ret);
19194   return ret;
19195 }
19196
19197 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19198 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19199
19200 static void
19201 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19202 {
19203   vat_main_t *vam = &vat_main;
19204   int count = ntohl (mp->count);
19205   vl_api_fib_path_t *fp;
19206   int i;
19207
19208   print (vam->ofp,
19209          "table-id %d, prefix %U/%d",
19210          ntohl (mp->table_id), format_ip6_address, mp->address,
19211          mp->address_length);
19212   fp = mp->path;
19213   for (i = 0; i < count; i++)
19214     {
19215       if (fp->afi == IP46_TYPE_IP6)
19216         print (vam->ofp,
19217                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19218                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19219                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19220                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19221                format_ip6_address, fp->next_hop);
19222       else if (fp->afi == IP46_TYPE_IP4)
19223         print (vam->ofp,
19224                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19225                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19226                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19227                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19228                format_ip4_address, fp->next_hop);
19229       fp++;
19230     }
19231 }
19232
19233 static void vl_api_ip6_fib_details_t_handler_json
19234   (vl_api_ip6_fib_details_t * mp)
19235 {
19236   vat_main_t *vam = &vat_main;
19237   int count = ntohl (mp->count);
19238   vat_json_node_t *node = NULL;
19239   struct in_addr ip4;
19240   struct in6_addr ip6;
19241   vl_api_fib_path_t *fp;
19242   int i;
19243
19244   if (VAT_JSON_ARRAY != vam->json_tree.type)
19245     {
19246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19247       vat_json_init_array (&vam->json_tree);
19248     }
19249   node = vat_json_array_add (&vam->json_tree);
19250
19251   vat_json_init_object (node);
19252   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19253   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19254   vat_json_object_add_ip6 (node, "prefix", ip6);
19255   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19256   vat_json_object_add_uint (node, "path_count", count);
19257   fp = mp->path;
19258   for (i = 0; i < count; i++)
19259     {
19260       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19261       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19262       vat_json_object_add_uint (node, "is_local", fp->is_local);
19263       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19264       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19265       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19266       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19267       if (fp->afi == IP46_TYPE_IP4)
19268         {
19269           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19270           vat_json_object_add_ip4 (node, "next_hop", ip4);
19271         }
19272       else if (fp->afi == IP46_TYPE_IP6)
19273         {
19274           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19275           vat_json_object_add_ip6 (node, "next_hop", ip6);
19276         }
19277     }
19278 }
19279
19280 static int
19281 api_ip6_fib_dump (vat_main_t * vam)
19282 {
19283   vl_api_ip6_fib_dump_t *mp;
19284   vl_api_control_ping_t *mp_ping;
19285   int ret;
19286
19287   M (IP6_FIB_DUMP, mp);
19288   S (mp);
19289
19290   /* Use a control ping for synchronization */
19291   MPING (CONTROL_PING, mp_ping);
19292   S (mp_ping);
19293
19294   W (ret);
19295   return ret;
19296 }
19297
19298 static int
19299 api_ip6_mfib_dump (vat_main_t * vam)
19300 {
19301   vl_api_ip6_mfib_dump_t *mp;
19302   vl_api_control_ping_t *mp_ping;
19303   int ret;
19304
19305   M (IP6_MFIB_DUMP, mp);
19306   S (mp);
19307
19308   /* Use a control ping for synchronization */
19309   MPING (CONTROL_PING, mp_ping);
19310   S (mp_ping);
19311
19312   W (ret);
19313   return ret;
19314 }
19315
19316 int
19317 api_classify_table_ids (vat_main_t * vam)
19318 {
19319   vl_api_classify_table_ids_t *mp;
19320   int ret;
19321
19322   /* Construct the API message */
19323   M (CLASSIFY_TABLE_IDS, mp);
19324   mp->context = 0;
19325
19326   S (mp);
19327   W (ret);
19328   return ret;
19329 }
19330
19331 int
19332 api_classify_table_by_interface (vat_main_t * vam)
19333 {
19334   unformat_input_t *input = vam->input;
19335   vl_api_classify_table_by_interface_t *mp;
19336
19337   u32 sw_if_index = ~0;
19338   int ret;
19339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19340     {
19341       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19342         ;
19343       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19344         ;
19345       else
19346         break;
19347     }
19348   if (sw_if_index == ~0)
19349     {
19350       errmsg ("missing interface name or sw_if_index");
19351       return -99;
19352     }
19353
19354   /* Construct the API message */
19355   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19356   mp->context = 0;
19357   mp->sw_if_index = ntohl (sw_if_index);
19358
19359   S (mp);
19360   W (ret);
19361   return ret;
19362 }
19363
19364 int
19365 api_classify_table_info (vat_main_t * vam)
19366 {
19367   unformat_input_t *input = vam->input;
19368   vl_api_classify_table_info_t *mp;
19369
19370   u32 table_id = ~0;
19371   int ret;
19372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19373     {
19374       if (unformat (input, "table_id %d", &table_id))
19375         ;
19376       else
19377         break;
19378     }
19379   if (table_id == ~0)
19380     {
19381       errmsg ("missing table id");
19382       return -99;
19383     }
19384
19385   /* Construct the API message */
19386   M (CLASSIFY_TABLE_INFO, mp);
19387   mp->context = 0;
19388   mp->table_id = ntohl (table_id);
19389
19390   S (mp);
19391   W (ret);
19392   return ret;
19393 }
19394
19395 int
19396 api_classify_session_dump (vat_main_t * vam)
19397 {
19398   unformat_input_t *input = vam->input;
19399   vl_api_classify_session_dump_t *mp;
19400   vl_api_control_ping_t *mp_ping;
19401
19402   u32 table_id = ~0;
19403   int ret;
19404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (input, "table_id %d", &table_id))
19407         ;
19408       else
19409         break;
19410     }
19411   if (table_id == ~0)
19412     {
19413       errmsg ("missing table id");
19414       return -99;
19415     }
19416
19417   /* Construct the API message */
19418   M (CLASSIFY_SESSION_DUMP, mp);
19419   mp->context = 0;
19420   mp->table_id = ntohl (table_id);
19421   S (mp);
19422
19423   /* Use a control ping for synchronization */
19424   MPING (CONTROL_PING, mp_ping);
19425   S (mp_ping);
19426
19427   W (ret);
19428   return ret;
19429 }
19430
19431 static void
19432 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19433 {
19434   vat_main_t *vam = &vat_main;
19435
19436   print (vam->ofp, "collector_address %U, collector_port %d, "
19437          "src_address %U, vrf_id %d, path_mtu %u, "
19438          "template_interval %u, udp_checksum %d",
19439          format_ip4_address, mp->collector_address,
19440          ntohs (mp->collector_port),
19441          format_ip4_address, mp->src_address,
19442          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19443          ntohl (mp->template_interval), mp->udp_checksum);
19444
19445   vam->retval = 0;
19446   vam->result_ready = 1;
19447 }
19448
19449 static void
19450   vl_api_ipfix_exporter_details_t_handler_json
19451   (vl_api_ipfix_exporter_details_t * mp)
19452 {
19453   vat_main_t *vam = &vat_main;
19454   vat_json_node_t node;
19455   struct in_addr collector_address;
19456   struct in_addr src_address;
19457
19458   vat_json_init_object (&node);
19459   clib_memcpy (&collector_address, &mp->collector_address,
19460                sizeof (collector_address));
19461   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19462   vat_json_object_add_uint (&node, "collector_port",
19463                             ntohs (mp->collector_port));
19464   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19465   vat_json_object_add_ip4 (&node, "src_address", src_address);
19466   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19467   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19468   vat_json_object_add_uint (&node, "template_interval",
19469                             ntohl (mp->template_interval));
19470   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19471
19472   vat_json_print (vam->ofp, &node);
19473   vat_json_free (&node);
19474   vam->retval = 0;
19475   vam->result_ready = 1;
19476 }
19477
19478 int
19479 api_ipfix_exporter_dump (vat_main_t * vam)
19480 {
19481   vl_api_ipfix_exporter_dump_t *mp;
19482   int ret;
19483
19484   /* Construct the API message */
19485   M (IPFIX_EXPORTER_DUMP, mp);
19486   mp->context = 0;
19487
19488   S (mp);
19489   W (ret);
19490   return ret;
19491 }
19492
19493 static int
19494 api_ipfix_classify_stream_dump (vat_main_t * vam)
19495 {
19496   vl_api_ipfix_classify_stream_dump_t *mp;
19497   int ret;
19498
19499   /* Construct the API message */
19500   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19501   mp->context = 0;
19502
19503   S (mp);
19504   W (ret);
19505   return ret;
19506   /* NOTREACHED */
19507   return 0;
19508 }
19509
19510 static void
19511   vl_api_ipfix_classify_stream_details_t_handler
19512   (vl_api_ipfix_classify_stream_details_t * mp)
19513 {
19514   vat_main_t *vam = &vat_main;
19515   print (vam->ofp, "domain_id %d, src_port %d",
19516          ntohl (mp->domain_id), ntohs (mp->src_port));
19517   vam->retval = 0;
19518   vam->result_ready = 1;
19519 }
19520
19521 static void
19522   vl_api_ipfix_classify_stream_details_t_handler_json
19523   (vl_api_ipfix_classify_stream_details_t * mp)
19524 {
19525   vat_main_t *vam = &vat_main;
19526   vat_json_node_t node;
19527
19528   vat_json_init_object (&node);
19529   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19530   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19531
19532   vat_json_print (vam->ofp, &node);
19533   vat_json_free (&node);
19534   vam->retval = 0;
19535   vam->result_ready = 1;
19536 }
19537
19538 static int
19539 api_ipfix_classify_table_dump (vat_main_t * vam)
19540 {
19541   vl_api_ipfix_classify_table_dump_t *mp;
19542   vl_api_control_ping_t *mp_ping;
19543   int ret;
19544
19545   if (!vam->json_output)
19546     {
19547       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19548              "transport_protocol");
19549     }
19550
19551   /* Construct the API message */
19552   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19553
19554   /* send it... */
19555   S (mp);
19556
19557   /* Use a control ping for synchronization */
19558   MPING (CONTROL_PING, mp_ping);
19559   S (mp_ping);
19560
19561   W (ret);
19562   return ret;
19563 }
19564
19565 static void
19566   vl_api_ipfix_classify_table_details_t_handler
19567   (vl_api_ipfix_classify_table_details_t * mp)
19568 {
19569   vat_main_t *vam = &vat_main;
19570   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19571          mp->transport_protocol);
19572 }
19573
19574 static void
19575   vl_api_ipfix_classify_table_details_t_handler_json
19576   (vl_api_ipfix_classify_table_details_t * mp)
19577 {
19578   vat_json_node_t *node = NULL;
19579   vat_main_t *vam = &vat_main;
19580
19581   if (VAT_JSON_ARRAY != vam->json_tree.type)
19582     {
19583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19584       vat_json_init_array (&vam->json_tree);
19585     }
19586
19587   node = vat_json_array_add (&vam->json_tree);
19588   vat_json_init_object (node);
19589
19590   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19591   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19592   vat_json_object_add_uint (node, "transport_protocol",
19593                             mp->transport_protocol);
19594 }
19595
19596 static int
19597 api_sw_interface_span_enable_disable (vat_main_t * vam)
19598 {
19599   unformat_input_t *i = vam->input;
19600   vl_api_sw_interface_span_enable_disable_t *mp;
19601   u32 src_sw_if_index = ~0;
19602   u32 dst_sw_if_index = ~0;
19603   u8 state = 3;
19604   int ret;
19605   u8 is_l2 = 0;
19606
19607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19608     {
19609       if (unformat
19610           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19611         ;
19612       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19613         ;
19614       else
19615         if (unformat
19616             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19617         ;
19618       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19619         ;
19620       else if (unformat (i, "disable"))
19621         state = 0;
19622       else if (unformat (i, "rx"))
19623         state = 1;
19624       else if (unformat (i, "tx"))
19625         state = 2;
19626       else if (unformat (i, "both"))
19627         state = 3;
19628       else if (unformat (i, "l2"))
19629         is_l2 = 1;
19630       else
19631         break;
19632     }
19633
19634   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19635
19636   mp->sw_if_index_from = htonl (src_sw_if_index);
19637   mp->sw_if_index_to = htonl (dst_sw_if_index);
19638   mp->state = state;
19639   mp->is_l2 = is_l2;
19640
19641   S (mp);
19642   W (ret);
19643   return ret;
19644 }
19645
19646 static void
19647 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19648                                             * mp)
19649 {
19650   vat_main_t *vam = &vat_main;
19651   u8 *sw_if_from_name = 0;
19652   u8 *sw_if_to_name = 0;
19653   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19654   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19655   char *states[] = { "none", "rx", "tx", "both" };
19656   hash_pair_t *p;
19657
19658   /* *INDENT-OFF* */
19659   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19660   ({
19661     if ((u32) p->value[0] == sw_if_index_from)
19662       {
19663         sw_if_from_name = (u8 *)(p->key);
19664         if (sw_if_to_name)
19665           break;
19666       }
19667     if ((u32) p->value[0] == sw_if_index_to)
19668       {
19669         sw_if_to_name = (u8 *)(p->key);
19670         if (sw_if_from_name)
19671           break;
19672       }
19673   }));
19674   /* *INDENT-ON* */
19675   print (vam->ofp, "%20s => %20s (%s)",
19676          sw_if_from_name, sw_if_to_name, states[mp->state]);
19677 }
19678
19679 static void
19680   vl_api_sw_interface_span_details_t_handler_json
19681   (vl_api_sw_interface_span_details_t * mp)
19682 {
19683   vat_main_t *vam = &vat_main;
19684   vat_json_node_t *node = NULL;
19685   u8 *sw_if_from_name = 0;
19686   u8 *sw_if_to_name = 0;
19687   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19688   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19689   hash_pair_t *p;
19690
19691   /* *INDENT-OFF* */
19692   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19693   ({
19694     if ((u32) p->value[0] == sw_if_index_from)
19695       {
19696         sw_if_from_name = (u8 *)(p->key);
19697         if (sw_if_to_name)
19698           break;
19699       }
19700     if ((u32) p->value[0] == sw_if_index_to)
19701       {
19702         sw_if_to_name = (u8 *)(p->key);
19703         if (sw_if_from_name)
19704           break;
19705       }
19706   }));
19707   /* *INDENT-ON* */
19708
19709   if (VAT_JSON_ARRAY != vam->json_tree.type)
19710     {
19711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19712       vat_json_init_array (&vam->json_tree);
19713     }
19714   node = vat_json_array_add (&vam->json_tree);
19715
19716   vat_json_init_object (node);
19717   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19718   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19719   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19720   if (0 != sw_if_to_name)
19721     {
19722       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19723     }
19724   vat_json_object_add_uint (node, "state", mp->state);
19725 }
19726
19727 static int
19728 api_sw_interface_span_dump (vat_main_t * vam)
19729 {
19730   unformat_input_t *input = vam->input;
19731   vl_api_sw_interface_span_dump_t *mp;
19732   vl_api_control_ping_t *mp_ping;
19733   u8 is_l2 = 0;
19734   int ret;
19735
19736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19737     {
19738       if (unformat (input, "l2"))
19739         is_l2 = 1;
19740       else
19741         break;
19742     }
19743
19744   M (SW_INTERFACE_SPAN_DUMP, mp);
19745   mp->is_l2 = is_l2;
19746   S (mp);
19747
19748   /* Use a control ping for synchronization */
19749   MPING (CONTROL_PING, mp_ping);
19750   S (mp_ping);
19751
19752   W (ret);
19753   return ret;
19754 }
19755
19756 int
19757 api_pg_create_interface (vat_main_t * vam)
19758 {
19759   unformat_input_t *input = vam->input;
19760   vl_api_pg_create_interface_t *mp;
19761
19762   u32 if_id = ~0;
19763   int ret;
19764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19765     {
19766       if (unformat (input, "if_id %d", &if_id))
19767         ;
19768       else
19769         break;
19770     }
19771   if (if_id == ~0)
19772     {
19773       errmsg ("missing pg interface index");
19774       return -99;
19775     }
19776
19777   /* Construct the API message */
19778   M (PG_CREATE_INTERFACE, mp);
19779   mp->context = 0;
19780   mp->interface_id = ntohl (if_id);
19781
19782   S (mp);
19783   W (ret);
19784   return ret;
19785 }
19786
19787 int
19788 api_pg_capture (vat_main_t * vam)
19789 {
19790   unformat_input_t *input = vam->input;
19791   vl_api_pg_capture_t *mp;
19792
19793   u32 if_id = ~0;
19794   u8 enable = 1;
19795   u32 count = 1;
19796   u8 pcap_file_set = 0;
19797   u8 *pcap_file = 0;
19798   int ret;
19799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19800     {
19801       if (unformat (input, "if_id %d", &if_id))
19802         ;
19803       else if (unformat (input, "pcap %s", &pcap_file))
19804         pcap_file_set = 1;
19805       else if (unformat (input, "count %d", &count))
19806         ;
19807       else if (unformat (input, "disable"))
19808         enable = 0;
19809       else
19810         break;
19811     }
19812   if (if_id == ~0)
19813     {
19814       errmsg ("missing pg interface index");
19815       return -99;
19816     }
19817   if (pcap_file_set > 0)
19818     {
19819       if (vec_len (pcap_file) > 255)
19820         {
19821           errmsg ("pcap file name is too long");
19822           return -99;
19823         }
19824     }
19825
19826   u32 name_len = vec_len (pcap_file);
19827   /* Construct the API message */
19828   M (PG_CAPTURE, mp);
19829   mp->context = 0;
19830   mp->interface_id = ntohl (if_id);
19831   mp->is_enabled = enable;
19832   mp->count = ntohl (count);
19833   mp->pcap_name_length = ntohl (name_len);
19834   if (pcap_file_set != 0)
19835     {
19836       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19837     }
19838   vec_free (pcap_file);
19839
19840   S (mp);
19841   W (ret);
19842   return ret;
19843 }
19844
19845 int
19846 api_pg_enable_disable (vat_main_t * vam)
19847 {
19848   unformat_input_t *input = vam->input;
19849   vl_api_pg_enable_disable_t *mp;
19850
19851   u8 enable = 1;
19852   u8 stream_name_set = 0;
19853   u8 *stream_name = 0;
19854   int ret;
19855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19856     {
19857       if (unformat (input, "stream %s", &stream_name))
19858         stream_name_set = 1;
19859       else if (unformat (input, "disable"))
19860         enable = 0;
19861       else
19862         break;
19863     }
19864
19865   if (stream_name_set > 0)
19866     {
19867       if (vec_len (stream_name) > 255)
19868         {
19869           errmsg ("stream name too long");
19870           return -99;
19871         }
19872     }
19873
19874   u32 name_len = vec_len (stream_name);
19875   /* Construct the API message */
19876   M (PG_ENABLE_DISABLE, mp);
19877   mp->context = 0;
19878   mp->is_enabled = enable;
19879   if (stream_name_set != 0)
19880     {
19881       mp->stream_name_length = ntohl (name_len);
19882       clib_memcpy (mp->stream_name, stream_name, name_len);
19883     }
19884   vec_free (stream_name);
19885
19886   S (mp);
19887   W (ret);
19888   return ret;
19889 }
19890
19891 int
19892 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19893 {
19894   unformat_input_t *input = vam->input;
19895   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19896
19897   u16 *low_ports = 0;
19898   u16 *high_ports = 0;
19899   u16 this_low;
19900   u16 this_hi;
19901   ip4_address_t ip4_addr;
19902   ip6_address_t ip6_addr;
19903   u32 length;
19904   u32 tmp, tmp2;
19905   u8 prefix_set = 0;
19906   u32 vrf_id = ~0;
19907   u8 is_add = 1;
19908   u8 is_ipv6 = 0;
19909   int ret;
19910
19911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19912     {
19913       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19914         {
19915           prefix_set = 1;
19916         }
19917       else
19918         if (unformat
19919             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19920         {
19921           prefix_set = 1;
19922           is_ipv6 = 1;
19923         }
19924       else if (unformat (input, "vrf %d", &vrf_id))
19925         ;
19926       else if (unformat (input, "del"))
19927         is_add = 0;
19928       else if (unformat (input, "port %d", &tmp))
19929         {
19930           if (tmp == 0 || tmp > 65535)
19931             {
19932               errmsg ("port %d out of range", tmp);
19933               return -99;
19934             }
19935           this_low = tmp;
19936           this_hi = this_low + 1;
19937           vec_add1 (low_ports, this_low);
19938           vec_add1 (high_ports, this_hi);
19939         }
19940       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19941         {
19942           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19943             {
19944               errmsg ("incorrect range parameters");
19945               return -99;
19946             }
19947           this_low = tmp;
19948           /* Note: in debug CLI +1 is added to high before
19949              passing to real fn that does "the work"
19950              (ip_source_and_port_range_check_add_del).
19951              This fn is a wrapper around the binary API fn a
19952              control plane will call, which expects this increment
19953              to have occurred. Hence letting the binary API control
19954              plane fn do the increment for consistency between VAT
19955              and other control planes.
19956            */
19957           this_hi = tmp2;
19958           vec_add1 (low_ports, this_low);
19959           vec_add1 (high_ports, this_hi);
19960         }
19961       else
19962         break;
19963     }
19964
19965   if (prefix_set == 0)
19966     {
19967       errmsg ("<address>/<mask> not specified");
19968       return -99;
19969     }
19970
19971   if (vrf_id == ~0)
19972     {
19973       errmsg ("VRF ID required, not specified");
19974       return -99;
19975     }
19976
19977   if (vrf_id == 0)
19978     {
19979       errmsg
19980         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19981       return -99;
19982     }
19983
19984   if (vec_len (low_ports) == 0)
19985     {
19986       errmsg ("At least one port or port range required");
19987       return -99;
19988     }
19989
19990   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19991
19992   mp->is_add = is_add;
19993
19994   if (is_ipv6)
19995     {
19996       mp->is_ipv6 = 1;
19997       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19998     }
19999   else
20000     {
20001       mp->is_ipv6 = 0;
20002       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20003     }
20004
20005   mp->mask_length = length;
20006   mp->number_of_ranges = vec_len (low_ports);
20007
20008   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20009   vec_free (low_ports);
20010
20011   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20012   vec_free (high_ports);
20013
20014   mp->vrf_id = ntohl (vrf_id);
20015
20016   S (mp);
20017   W (ret);
20018   return ret;
20019 }
20020
20021 int
20022 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20023 {
20024   unformat_input_t *input = vam->input;
20025   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20026   u32 sw_if_index = ~0;
20027   int vrf_set = 0;
20028   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20029   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20030   u8 is_add = 1;
20031   int ret;
20032
20033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20034     {
20035       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20036         ;
20037       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20038         ;
20039       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20040         vrf_set = 1;
20041       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20042         vrf_set = 1;
20043       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20044         vrf_set = 1;
20045       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20046         vrf_set = 1;
20047       else if (unformat (input, "del"))
20048         is_add = 0;
20049       else
20050         break;
20051     }
20052
20053   if (sw_if_index == ~0)
20054     {
20055       errmsg ("Interface required but not specified");
20056       return -99;
20057     }
20058
20059   if (vrf_set == 0)
20060     {
20061       errmsg ("VRF ID required but not specified");
20062       return -99;
20063     }
20064
20065   if (tcp_out_vrf_id == 0
20066       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20067     {
20068       errmsg
20069         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20070       return -99;
20071     }
20072
20073   /* Construct the API message */
20074   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20075
20076   mp->sw_if_index = ntohl (sw_if_index);
20077   mp->is_add = is_add;
20078   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20079   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20080   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20081   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20082
20083   /* send it... */
20084   S (mp);
20085
20086   /* Wait for a reply... */
20087   W (ret);
20088   return ret;
20089 }
20090
20091 static int
20092 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20093 {
20094   unformat_input_t *i = vam->input;
20095   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20096   u32 local_sa_id = 0;
20097   u32 remote_sa_id = 0;
20098   ip4_address_t src_address;
20099   ip4_address_t dst_address;
20100   u8 is_add = 1;
20101   int ret;
20102
20103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20104     {
20105       if (unformat (i, "local_sa %d", &local_sa_id))
20106         ;
20107       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20108         ;
20109       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20110         ;
20111       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20112         ;
20113       else if (unformat (i, "del"))
20114         is_add = 0;
20115       else
20116         {
20117           clib_warning ("parse error '%U'", format_unformat_error, i);
20118           return -99;
20119         }
20120     }
20121
20122   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20123
20124   mp->local_sa_id = ntohl (local_sa_id);
20125   mp->remote_sa_id = ntohl (remote_sa_id);
20126   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20127   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20128   mp->is_add = is_add;
20129
20130   S (mp);
20131   W (ret);
20132   return ret;
20133 }
20134
20135 static int
20136 api_punt (vat_main_t * vam)
20137 {
20138   unformat_input_t *i = vam->input;
20139   vl_api_punt_t *mp;
20140   u32 ipv = ~0;
20141   u32 protocol = ~0;
20142   u32 port = ~0;
20143   int is_add = 1;
20144   int ret;
20145
20146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20147     {
20148       if (unformat (i, "ip %d", &ipv))
20149         ;
20150       else if (unformat (i, "protocol %d", &protocol))
20151         ;
20152       else if (unformat (i, "port %d", &port))
20153         ;
20154       else if (unformat (i, "del"))
20155         is_add = 0;
20156       else
20157         {
20158           clib_warning ("parse error '%U'", format_unformat_error, i);
20159           return -99;
20160         }
20161     }
20162
20163   M (PUNT, mp);
20164
20165   mp->is_add = (u8) is_add;
20166   mp->ipv = (u8) ipv;
20167   mp->l4_protocol = (u8) protocol;
20168   mp->l4_port = htons ((u16) port);
20169
20170   S (mp);
20171   W (ret);
20172   return ret;
20173 }
20174
20175 static void vl_api_ipsec_gre_tunnel_details_t_handler
20176   (vl_api_ipsec_gre_tunnel_details_t * mp)
20177 {
20178   vat_main_t *vam = &vat_main;
20179
20180   print (vam->ofp, "%11d%15U%15U%14d%14d",
20181          ntohl (mp->sw_if_index),
20182          format_ip4_address, &mp->src_address,
20183          format_ip4_address, &mp->dst_address,
20184          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20185 }
20186
20187 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20188   (vl_api_ipsec_gre_tunnel_details_t * mp)
20189 {
20190   vat_main_t *vam = &vat_main;
20191   vat_json_node_t *node = NULL;
20192   struct in_addr ip4;
20193
20194   if (VAT_JSON_ARRAY != vam->json_tree.type)
20195     {
20196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20197       vat_json_init_array (&vam->json_tree);
20198     }
20199   node = vat_json_array_add (&vam->json_tree);
20200
20201   vat_json_init_object (node);
20202   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20203   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20204   vat_json_object_add_ip4 (node, "src_address", ip4);
20205   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20206   vat_json_object_add_ip4 (node, "dst_address", ip4);
20207   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20208   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20209 }
20210
20211 static int
20212 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20213 {
20214   unformat_input_t *i = vam->input;
20215   vl_api_ipsec_gre_tunnel_dump_t *mp;
20216   vl_api_control_ping_t *mp_ping;
20217   u32 sw_if_index;
20218   u8 sw_if_index_set = 0;
20219   int ret;
20220
20221   /* Parse args required to build the message */
20222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20223     {
20224       if (unformat (i, "sw_if_index %d", &sw_if_index))
20225         sw_if_index_set = 1;
20226       else
20227         break;
20228     }
20229
20230   if (sw_if_index_set == 0)
20231     {
20232       sw_if_index = ~0;
20233     }
20234
20235   if (!vam->json_output)
20236     {
20237       print (vam->ofp, "%11s%15s%15s%14s%14s",
20238              "sw_if_index", "src_address", "dst_address",
20239              "local_sa_id", "remote_sa_id");
20240     }
20241
20242   /* Get list of gre-tunnel interfaces */
20243   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20244
20245   mp->sw_if_index = htonl (sw_if_index);
20246
20247   S (mp);
20248
20249   /* Use a control ping for synchronization */
20250   MPING (CONTROL_PING, mp_ping);
20251   S (mp_ping);
20252
20253   W (ret);
20254   return ret;
20255 }
20256
20257 static int
20258 api_delete_subif (vat_main_t * vam)
20259 {
20260   unformat_input_t *i = vam->input;
20261   vl_api_delete_subif_t *mp;
20262   u32 sw_if_index = ~0;
20263   int ret;
20264
20265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20266     {
20267       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20268         ;
20269       if (unformat (i, "sw_if_index %d", &sw_if_index))
20270         ;
20271       else
20272         break;
20273     }
20274
20275   if (sw_if_index == ~0)
20276     {
20277       errmsg ("missing sw_if_index");
20278       return -99;
20279     }
20280
20281   /* Construct the API message */
20282   M (DELETE_SUBIF, mp);
20283   mp->sw_if_index = ntohl (sw_if_index);
20284
20285   S (mp);
20286   W (ret);
20287   return ret;
20288 }
20289
20290 #define foreach_pbb_vtr_op      \
20291 _("disable",  L2_VTR_DISABLED)  \
20292 _("pop",  L2_VTR_POP_2)         \
20293 _("push",  L2_VTR_PUSH_2)
20294
20295 static int
20296 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20297 {
20298   unformat_input_t *i = vam->input;
20299   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20300   u32 sw_if_index = ~0, vtr_op = ~0;
20301   u16 outer_tag = ~0;
20302   u8 dmac[6], smac[6];
20303   u8 dmac_set = 0, smac_set = 0;
20304   u16 vlanid = 0;
20305   u32 sid = ~0;
20306   u32 tmp;
20307   int ret;
20308
20309   /* Shut up coverity */
20310   memset (dmac, 0, sizeof (dmac));
20311   memset (smac, 0, sizeof (smac));
20312
20313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20314     {
20315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20316         ;
20317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20318         ;
20319       else if (unformat (i, "vtr_op %d", &vtr_op))
20320         ;
20321 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20322       foreach_pbb_vtr_op
20323 #undef _
20324         else if (unformat (i, "translate_pbb_stag"))
20325         {
20326           if (unformat (i, "%d", &tmp))
20327             {
20328               vtr_op = L2_VTR_TRANSLATE_2_1;
20329               outer_tag = tmp;
20330             }
20331           else
20332             {
20333               errmsg
20334                 ("translate_pbb_stag operation requires outer tag definition");
20335               return -99;
20336             }
20337         }
20338       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20339         dmac_set++;
20340       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20341         smac_set++;
20342       else if (unformat (i, "sid %d", &sid))
20343         ;
20344       else if (unformat (i, "vlanid %d", &tmp))
20345         vlanid = tmp;
20346       else
20347         {
20348           clib_warning ("parse error '%U'", format_unformat_error, i);
20349           return -99;
20350         }
20351     }
20352
20353   if ((sw_if_index == ~0) || (vtr_op == ~0))
20354     {
20355       errmsg ("missing sw_if_index or vtr operation");
20356       return -99;
20357     }
20358   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20359       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20360     {
20361       errmsg
20362         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20363       return -99;
20364     }
20365
20366   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20367   mp->sw_if_index = ntohl (sw_if_index);
20368   mp->vtr_op = ntohl (vtr_op);
20369   mp->outer_tag = ntohs (outer_tag);
20370   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20371   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20372   mp->b_vlanid = ntohs (vlanid);
20373   mp->i_sid = ntohl (sid);
20374
20375   S (mp);
20376   W (ret);
20377   return ret;
20378 }
20379
20380 static int
20381 api_flow_classify_set_interface (vat_main_t * vam)
20382 {
20383   unformat_input_t *i = vam->input;
20384   vl_api_flow_classify_set_interface_t *mp;
20385   u32 sw_if_index;
20386   int sw_if_index_set;
20387   u32 ip4_table_index = ~0;
20388   u32 ip6_table_index = ~0;
20389   u8 is_add = 1;
20390   int ret;
20391
20392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20393     {
20394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20395         sw_if_index_set = 1;
20396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20397         sw_if_index_set = 1;
20398       else if (unformat (i, "del"))
20399         is_add = 0;
20400       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20401         ;
20402       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20403         ;
20404       else
20405         {
20406           clib_warning ("parse error '%U'", format_unformat_error, i);
20407           return -99;
20408         }
20409     }
20410
20411   if (sw_if_index_set == 0)
20412     {
20413       errmsg ("missing interface name or sw_if_index");
20414       return -99;
20415     }
20416
20417   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20418
20419   mp->sw_if_index = ntohl (sw_if_index);
20420   mp->ip4_table_index = ntohl (ip4_table_index);
20421   mp->ip6_table_index = ntohl (ip6_table_index);
20422   mp->is_add = is_add;
20423
20424   S (mp);
20425   W (ret);
20426   return ret;
20427 }
20428
20429 static int
20430 api_flow_classify_dump (vat_main_t * vam)
20431 {
20432   unformat_input_t *i = vam->input;
20433   vl_api_flow_classify_dump_t *mp;
20434   vl_api_control_ping_t *mp_ping;
20435   u8 type = FLOW_CLASSIFY_N_TABLES;
20436   int ret;
20437
20438   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20439     ;
20440   else
20441     {
20442       errmsg ("classify table type must be specified");
20443       return -99;
20444     }
20445
20446   if (!vam->json_output)
20447     {
20448       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20449     }
20450
20451   M (FLOW_CLASSIFY_DUMP, mp);
20452   mp->type = type;
20453   /* send it... */
20454   S (mp);
20455
20456   /* Use a control ping for synchronization */
20457   MPING (CONTROL_PING, mp_ping);
20458   S (mp_ping);
20459
20460   /* Wait for a reply... */
20461   W (ret);
20462   return ret;
20463 }
20464
20465 static int
20466 api_feature_enable_disable (vat_main_t * vam)
20467 {
20468   unformat_input_t *i = vam->input;
20469   vl_api_feature_enable_disable_t *mp;
20470   u8 *arc_name = 0;
20471   u8 *feature_name = 0;
20472   u32 sw_if_index = ~0;
20473   u8 enable = 1;
20474   int ret;
20475
20476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20477     {
20478       if (unformat (i, "arc_name %s", &arc_name))
20479         ;
20480       else if (unformat (i, "feature_name %s", &feature_name))
20481         ;
20482       else
20483         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20484         ;
20485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20486         ;
20487       else if (unformat (i, "disable"))
20488         enable = 0;
20489       else
20490         break;
20491     }
20492
20493   if (arc_name == 0)
20494     {
20495       errmsg ("missing arc name");
20496       return -99;
20497     }
20498   if (vec_len (arc_name) > 63)
20499     {
20500       errmsg ("arc name too long");
20501     }
20502
20503   if (feature_name == 0)
20504     {
20505       errmsg ("missing feature name");
20506       return -99;
20507     }
20508   if (vec_len (feature_name) > 63)
20509     {
20510       errmsg ("feature name too long");
20511     }
20512
20513   if (sw_if_index == ~0)
20514     {
20515       errmsg ("missing interface name or sw_if_index");
20516       return -99;
20517     }
20518
20519   /* Construct the API message */
20520   M (FEATURE_ENABLE_DISABLE, mp);
20521   mp->sw_if_index = ntohl (sw_if_index);
20522   mp->enable = enable;
20523   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20524   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20525   vec_free (arc_name);
20526   vec_free (feature_name);
20527
20528   S (mp);
20529   W (ret);
20530   return ret;
20531 }
20532
20533 static int
20534 api_sw_interface_tag_add_del (vat_main_t * vam)
20535 {
20536   unformat_input_t *i = vam->input;
20537   vl_api_sw_interface_tag_add_del_t *mp;
20538   u32 sw_if_index = ~0;
20539   u8 *tag = 0;
20540   u8 enable = 1;
20541   int ret;
20542
20543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (i, "tag %s", &tag))
20546         ;
20547       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20548         ;
20549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20550         ;
20551       else if (unformat (i, "del"))
20552         enable = 0;
20553       else
20554         break;
20555     }
20556
20557   if (sw_if_index == ~0)
20558     {
20559       errmsg ("missing interface name or sw_if_index");
20560       return -99;
20561     }
20562
20563   if (enable && (tag == 0))
20564     {
20565       errmsg ("no tag specified");
20566       return -99;
20567     }
20568
20569   /* Construct the API message */
20570   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20571   mp->sw_if_index = ntohl (sw_if_index);
20572   mp->is_add = enable;
20573   if (enable)
20574     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20575   vec_free (tag);
20576
20577   S (mp);
20578   W (ret);
20579   return ret;
20580 }
20581
20582 static void vl_api_l2_xconnect_details_t_handler
20583   (vl_api_l2_xconnect_details_t * mp)
20584 {
20585   vat_main_t *vam = &vat_main;
20586
20587   print (vam->ofp, "%15d%15d",
20588          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20589 }
20590
20591 static void vl_api_l2_xconnect_details_t_handler_json
20592   (vl_api_l2_xconnect_details_t * mp)
20593 {
20594   vat_main_t *vam = &vat_main;
20595   vat_json_node_t *node = NULL;
20596
20597   if (VAT_JSON_ARRAY != vam->json_tree.type)
20598     {
20599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20600       vat_json_init_array (&vam->json_tree);
20601     }
20602   node = vat_json_array_add (&vam->json_tree);
20603
20604   vat_json_init_object (node);
20605   vat_json_object_add_uint (node, "rx_sw_if_index",
20606                             ntohl (mp->rx_sw_if_index));
20607   vat_json_object_add_uint (node, "tx_sw_if_index",
20608                             ntohl (mp->tx_sw_if_index));
20609 }
20610
20611 static int
20612 api_l2_xconnect_dump (vat_main_t * vam)
20613 {
20614   vl_api_l2_xconnect_dump_t *mp;
20615   vl_api_control_ping_t *mp_ping;
20616   int ret;
20617
20618   if (!vam->json_output)
20619     {
20620       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20621     }
20622
20623   M (L2_XCONNECT_DUMP, mp);
20624
20625   S (mp);
20626
20627   /* Use a control ping for synchronization */
20628   MPING (CONTROL_PING, mp_ping);
20629   S (mp_ping);
20630
20631   W (ret);
20632   return ret;
20633 }
20634
20635 static int
20636 api_sw_interface_set_mtu (vat_main_t * vam)
20637 {
20638   unformat_input_t *i = vam->input;
20639   vl_api_sw_interface_set_mtu_t *mp;
20640   u32 sw_if_index = ~0;
20641   u32 mtu = 0;
20642   int ret;
20643
20644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20645     {
20646       if (unformat (i, "mtu %d", &mtu))
20647         ;
20648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20649         ;
20650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20651         ;
20652       else
20653         break;
20654     }
20655
20656   if (sw_if_index == ~0)
20657     {
20658       errmsg ("missing interface name or sw_if_index");
20659       return -99;
20660     }
20661
20662   if (mtu == 0)
20663     {
20664       errmsg ("no mtu specified");
20665       return -99;
20666     }
20667
20668   /* Construct the API message */
20669   M (SW_INTERFACE_SET_MTU, mp);
20670   mp->sw_if_index = ntohl (sw_if_index);
20671   mp->mtu = ntohs ((u16) mtu);
20672
20673   S (mp);
20674   W (ret);
20675   return ret;
20676 }
20677
20678 static int
20679 api_p2p_ethernet_add (vat_main_t * vam)
20680 {
20681   unformat_input_t *i = vam->input;
20682   vl_api_p2p_ethernet_add_t *mp;
20683   u32 parent_if_index = ~0;
20684   u32 sub_id = ~0;
20685   u8 remote_mac[6];
20686   u8 mac_set = 0;
20687   int ret;
20688
20689   memset (remote_mac, 0, sizeof (remote_mac));
20690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20691     {
20692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20693         ;
20694       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20695         ;
20696       else
20697         if (unformat
20698             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20699         mac_set++;
20700       else if (unformat (i, "sub_id %d", &sub_id))
20701         ;
20702       else
20703         {
20704           clib_warning ("parse error '%U'", format_unformat_error, i);
20705           return -99;
20706         }
20707     }
20708
20709   if (parent_if_index == ~0)
20710     {
20711       errmsg ("missing interface name or sw_if_index");
20712       return -99;
20713     }
20714   if (mac_set == 0)
20715     {
20716       errmsg ("missing remote mac address");
20717       return -99;
20718     }
20719   if (sub_id == ~0)
20720     {
20721       errmsg ("missing sub-interface id");
20722       return -99;
20723     }
20724
20725   M (P2P_ETHERNET_ADD, mp);
20726   mp->parent_if_index = ntohl (parent_if_index);
20727   mp->subif_id = ntohl (sub_id);
20728   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20729
20730   S (mp);
20731   W (ret);
20732   return ret;
20733 }
20734
20735 static int
20736 api_p2p_ethernet_del (vat_main_t * vam)
20737 {
20738   unformat_input_t *i = vam->input;
20739   vl_api_p2p_ethernet_del_t *mp;
20740   u32 parent_if_index = ~0;
20741   u8 remote_mac[6];
20742   u8 mac_set = 0;
20743   int ret;
20744
20745   memset (remote_mac, 0, sizeof (remote_mac));
20746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20747     {
20748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20749         ;
20750       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20751         ;
20752       else
20753         if (unformat
20754             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20755         mac_set++;
20756       else
20757         {
20758           clib_warning ("parse error '%U'", format_unformat_error, i);
20759           return -99;
20760         }
20761     }
20762
20763   if (parent_if_index == ~0)
20764     {
20765       errmsg ("missing interface name or sw_if_index");
20766       return -99;
20767     }
20768   if (mac_set == 0)
20769     {
20770       errmsg ("missing remote mac address");
20771       return -99;
20772     }
20773
20774   M (P2P_ETHERNET_DEL, mp);
20775   mp->parent_if_index = ntohl (parent_if_index);
20776   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20777
20778   S (mp);
20779   W (ret);
20780   return ret;
20781 }
20782
20783 static int
20784 api_lldp_config (vat_main_t * vam)
20785 {
20786   unformat_input_t *i = vam->input;
20787   vl_api_lldp_config_t *mp;
20788   int tx_hold = 0;
20789   int tx_interval = 0;
20790   u8 *sys_name = NULL;
20791   int ret;
20792
20793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20794     {
20795       if (unformat (i, "system-name %s", &sys_name))
20796         ;
20797       else if (unformat (i, "tx-hold %d", &tx_hold))
20798         ;
20799       else if (unformat (i, "tx-interval %d", &tx_interval))
20800         ;
20801       else
20802         {
20803           clib_warning ("parse error '%U'", format_unformat_error, i);
20804           return -99;
20805         }
20806     }
20807
20808   vec_add1 (sys_name, 0);
20809
20810   M (LLDP_CONFIG, mp);
20811   mp->tx_hold = htonl (tx_hold);
20812   mp->tx_interval = htonl (tx_interval);
20813   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20814   vec_free (sys_name);
20815
20816   S (mp);
20817   W (ret);
20818   return ret;
20819 }
20820
20821 static int
20822 api_sw_interface_set_lldp (vat_main_t * vam)
20823 {
20824   unformat_input_t *i = vam->input;
20825   vl_api_sw_interface_set_lldp_t *mp;
20826   u32 sw_if_index = ~0;
20827   u32 enable = 1;
20828   u8 *port_desc = NULL, *mgmt_oid = NULL;
20829   ip4_address_t ip4_addr;
20830   ip6_address_t ip6_addr;
20831   int ret;
20832
20833   memset (&ip4_addr, 0, sizeof (ip4_addr));
20834   memset (&ip6_addr, 0, sizeof (ip6_addr));
20835
20836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20837     {
20838       if (unformat (i, "disable"))
20839         enable = 0;
20840       else
20841         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20842         ;
20843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20844         ;
20845       else if (unformat (i, "port-desc %s", &port_desc))
20846         ;
20847       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20848         ;
20849       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20850         ;
20851       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20852         ;
20853       else
20854         break;
20855     }
20856
20857   if (sw_if_index == ~0)
20858     {
20859       errmsg ("missing interface name or sw_if_index");
20860       return -99;
20861     }
20862
20863   /* Construct the API message */
20864   vec_add1 (port_desc, 0);
20865   vec_add1 (mgmt_oid, 0);
20866   M (SW_INTERFACE_SET_LLDP, mp);
20867   mp->sw_if_index = ntohl (sw_if_index);
20868   mp->enable = enable;
20869   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20870   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20871   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20872   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20873   vec_free (port_desc);
20874   vec_free (mgmt_oid);
20875
20876   S (mp);
20877   W (ret);
20878   return ret;
20879 }
20880
20881 static int
20882 api_tcp_configure_src_addresses (vat_main_t * vam)
20883 {
20884   vl_api_tcp_configure_src_addresses_t *mp;
20885   unformat_input_t *i = vam->input;
20886   ip4_address_t v4first, v4last;
20887   ip6_address_t v6first, v6last;
20888   u8 range_set = 0;
20889   u32 vrf_id = 0;
20890   int ret;
20891
20892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20893     {
20894       if (unformat (i, "%U - %U",
20895                     unformat_ip4_address, &v4first,
20896                     unformat_ip4_address, &v4last))
20897         {
20898           if (range_set)
20899             {
20900               errmsg ("one range per message (range already set)");
20901               return -99;
20902             }
20903           range_set = 1;
20904         }
20905       else if (unformat (i, "%U - %U",
20906                          unformat_ip6_address, &v6first,
20907                          unformat_ip6_address, &v6last))
20908         {
20909           if (range_set)
20910             {
20911               errmsg ("one range per message (range already set)");
20912               return -99;
20913             }
20914           range_set = 2;
20915         }
20916       else if (unformat (i, "vrf %d", &vrf_id))
20917         ;
20918       else
20919         break;
20920     }
20921
20922   if (range_set == 0)
20923     {
20924       errmsg ("address range not set");
20925       return -99;
20926     }
20927
20928   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20929   mp->vrf_id = ntohl (vrf_id);
20930   /* ipv6? */
20931   if (range_set == 2)
20932     {
20933       mp->is_ipv6 = 1;
20934       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20935       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20936     }
20937   else
20938     {
20939       mp->is_ipv6 = 0;
20940       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20941       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20942     }
20943   S (mp);
20944   W (ret);
20945   return ret;
20946 }
20947
20948 static int
20949 api_app_namespace_add_del (vat_main_t * vam)
20950 {
20951   vl_api_app_namespace_add_del_t *mp;
20952   unformat_input_t *i = vam->input;
20953   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20954   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20955   u64 secret;
20956   int ret;
20957
20958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20959     {
20960       if (unformat (i, "id %_%v%_", &ns_id))
20961         ;
20962       else if (unformat (i, "secret %lu", &secret))
20963         secret_set = 1;
20964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20965         sw_if_index_set = 1;
20966       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20967         ;
20968       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20969         ;
20970       else
20971         break;
20972     }
20973   if (!ns_id || !secret_set || !sw_if_index_set)
20974     {
20975       errmsg ("namespace id, secret and sw_if_index must be set");
20976       return -99;
20977     }
20978   if (vec_len (ns_id) > 64)
20979     {
20980       errmsg ("namespace id too long");
20981       return -99;
20982     }
20983   M (APP_NAMESPACE_ADD_DEL, mp);
20984
20985   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20986   mp->namespace_id_len = vec_len (ns_id);
20987   mp->secret = clib_host_to_net_u64 (secret);
20988   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20989   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20990   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20991   vec_free (ns_id);
20992   S (mp);
20993   W (ret);
20994   return ret;
20995 }
20996
20997 static int
20998 api_memfd_segment_create (vat_main_t * vam)
20999 {
21000 #if VPP_API_TEST_BUILTIN == 0
21001   unformat_input_t *i = vam->input;
21002   vl_api_memfd_segment_create_t *mp;
21003   u64 size = 64 << 20;
21004   int ret;
21005
21006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21007     {
21008       if (unformat (i, "size %U", unformat_memory_size, &size))
21009         ;
21010       else
21011         break;
21012     }
21013
21014   M (MEMFD_SEGMENT_CREATE, mp);
21015   mp->requested_size = size;
21016   S (mp);
21017   W (ret);
21018   return ret;
21019
21020 #else
21021   errmsg ("memfd_segment_create (builtin) not supported");
21022   return -99;
21023 #endif
21024 }
21025
21026 static int
21027 api_dns_enable_disable (vat_main_t * vam)
21028 {
21029   unformat_input_t *line_input = vam->input;
21030   vl_api_dns_enable_disable_t *mp;
21031   u8 enable_disable = 1;
21032   int ret;
21033
21034   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21035     {
21036       if (unformat (line_input, "disable"))
21037         enable_disable = 0;
21038       if (unformat (line_input, "enable"))
21039         enable_disable = 1;
21040       else
21041         break;
21042     }
21043
21044   /* Construct the API message */
21045   M (DNS_ENABLE_DISABLE, mp);
21046   mp->enable = enable_disable;
21047
21048   /* send it... */
21049   S (mp);
21050   /* Wait for the reply */
21051   W (ret);
21052   return ret;
21053 }
21054
21055 static int
21056 api_dns_resolve_name (vat_main_t * vam)
21057 {
21058   unformat_input_t *line_input = vam->input;
21059   vl_api_dns_resolve_name_t *mp;
21060   u8 *name = 0;
21061   int ret;
21062
21063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21064     {
21065       if (unformat (line_input, "%s", &name))
21066         ;
21067       else
21068         break;
21069     }
21070
21071   if (vec_len (name) > 127)
21072     {
21073       errmsg ("name too long");
21074       return -99;
21075     }
21076
21077   /* Construct the API message */
21078   M (DNS_RESOLVE_NAME, mp);
21079   memcpy (mp->name, name, vec_len (name));
21080   vec_free (name);
21081
21082   /* send it... */
21083   S (mp);
21084   /* Wait for the reply */
21085   W (ret);
21086   return ret;
21087 }
21088
21089 static int
21090 api_dns_resolve_ip (vat_main_t * vam)
21091 {
21092   unformat_input_t *line_input = vam->input;
21093   vl_api_dns_resolve_ip_t *mp;
21094   int is_ip6 = -1;
21095   ip4_address_t addr4;
21096   ip6_address_t addr6;
21097   int ret;
21098
21099   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21100     {
21101       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21102         is_ip6 = 1;
21103       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21104         is_ip6 = 0;
21105       else
21106         break;
21107     }
21108
21109   if (is_ip6 == -1)
21110     {
21111       errmsg ("missing address");
21112       return -99;
21113     }
21114
21115   /* Construct the API message */
21116   M (DNS_RESOLVE_IP, mp);
21117   mp->is_ip6 = is_ip6;
21118   if (is_ip6)
21119     memcpy (mp->address, &addr6, sizeof (addr6));
21120   else
21121     memcpy (mp->address, &addr4, sizeof (addr4));
21122
21123   /* send it... */
21124   S (mp);
21125   /* Wait for the reply */
21126   W (ret);
21127   return ret;
21128 }
21129
21130 static int
21131 api_dns_name_server_add_del (vat_main_t * vam)
21132 {
21133   unformat_input_t *i = vam->input;
21134   vl_api_dns_name_server_add_del_t *mp;
21135   u8 is_add = 1;
21136   ip6_address_t ip6_server;
21137   ip4_address_t ip4_server;
21138   int ip6_set = 0;
21139   int ip4_set = 0;
21140   int ret = 0;
21141
21142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21143     {
21144       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21145         ip6_set = 1;
21146       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21147         ip4_set = 1;
21148       else if (unformat (i, "del"))
21149         is_add = 0;
21150       else
21151         {
21152           clib_warning ("parse error '%U'", format_unformat_error, i);
21153           return -99;
21154         }
21155     }
21156
21157   if (ip4_set && ip6_set)
21158     {
21159       errmsg ("Only one server address allowed per message");
21160       return -99;
21161     }
21162   if ((ip4_set + ip6_set) == 0)
21163     {
21164       errmsg ("Server address required");
21165       return -99;
21166     }
21167
21168   /* Construct the API message */
21169   M (DNS_NAME_SERVER_ADD_DEL, mp);
21170
21171   if (ip6_set)
21172     {
21173       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21174       mp->is_ip6 = 1;
21175     }
21176   else
21177     {
21178       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21179       mp->is_ip6 = 0;
21180     }
21181
21182   mp->is_add = is_add;
21183
21184   /* send it... */
21185   S (mp);
21186
21187   /* Wait for a reply, return good/bad news  */
21188   W (ret);
21189   return ret;
21190 }
21191
21192
21193 static int
21194 q_or_quit (vat_main_t * vam)
21195 {
21196 #if VPP_API_TEST_BUILTIN == 0
21197   longjmp (vam->jump_buf, 1);
21198 #endif
21199   return 0;                     /* not so much */
21200 }
21201
21202 static int
21203 q (vat_main_t * vam)
21204 {
21205   return q_or_quit (vam);
21206 }
21207
21208 static int
21209 quit (vat_main_t * vam)
21210 {
21211   return q_or_quit (vam);
21212 }
21213
21214 static int
21215 comment (vat_main_t * vam)
21216 {
21217   return 0;
21218 }
21219
21220 static int
21221 cmd_cmp (void *a1, void *a2)
21222 {
21223   u8 **c1 = a1;
21224   u8 **c2 = a2;
21225
21226   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21227 }
21228
21229 static int
21230 help (vat_main_t * vam)
21231 {
21232   u8 **cmds = 0;
21233   u8 *name = 0;
21234   hash_pair_t *p;
21235   unformat_input_t *i = vam->input;
21236   int j;
21237
21238   if (unformat (i, "%s", &name))
21239     {
21240       uword *hs;
21241
21242       vec_add1 (name, 0);
21243
21244       hs = hash_get_mem (vam->help_by_name, name);
21245       if (hs)
21246         print (vam->ofp, "usage: %s %s", name, hs[0]);
21247       else
21248         print (vam->ofp, "No such msg / command '%s'", name);
21249       vec_free (name);
21250       return 0;
21251     }
21252
21253   print (vam->ofp, "Help is available for the following:");
21254
21255     /* *INDENT-OFF* */
21256     hash_foreach_pair (p, vam->function_by_name,
21257     ({
21258       vec_add1 (cmds, (u8 *)(p->key));
21259     }));
21260     /* *INDENT-ON* */
21261
21262   vec_sort_with_function (cmds, cmd_cmp);
21263
21264   for (j = 0; j < vec_len (cmds); j++)
21265     print (vam->ofp, "%s", cmds[j]);
21266
21267   vec_free (cmds);
21268   return 0;
21269 }
21270
21271 static int
21272 set (vat_main_t * vam)
21273 {
21274   u8 *name = 0, *value = 0;
21275   unformat_input_t *i = vam->input;
21276
21277   if (unformat (i, "%s", &name))
21278     {
21279       /* The input buffer is a vector, not a string. */
21280       value = vec_dup (i->buffer);
21281       vec_delete (value, i->index, 0);
21282       /* Almost certainly has a trailing newline */
21283       if (value[vec_len (value) - 1] == '\n')
21284         value[vec_len (value) - 1] = 0;
21285       /* Make sure it's a proper string, one way or the other */
21286       vec_add1 (value, 0);
21287       (void) clib_macro_set_value (&vam->macro_main,
21288                                    (char *) name, (char *) value);
21289     }
21290   else
21291     errmsg ("usage: set <name> <value>");
21292
21293   vec_free (name);
21294   vec_free (value);
21295   return 0;
21296 }
21297
21298 static int
21299 unset (vat_main_t * vam)
21300 {
21301   u8 *name = 0;
21302
21303   if (unformat (vam->input, "%s", &name))
21304     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21305       errmsg ("unset: %s wasn't set", name);
21306   vec_free (name);
21307   return 0;
21308 }
21309
21310 typedef struct
21311 {
21312   u8 *name;
21313   u8 *value;
21314 } macro_sort_t;
21315
21316
21317 static int
21318 macro_sort_cmp (void *a1, void *a2)
21319 {
21320   macro_sort_t *s1 = a1;
21321   macro_sort_t *s2 = a2;
21322
21323   return strcmp ((char *) (s1->name), (char *) (s2->name));
21324 }
21325
21326 static int
21327 dump_macro_table (vat_main_t * vam)
21328 {
21329   macro_sort_t *sort_me = 0, *sm;
21330   int i;
21331   hash_pair_t *p;
21332
21333     /* *INDENT-OFF* */
21334     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21335     ({
21336       vec_add2 (sort_me, sm, 1);
21337       sm->name = (u8 *)(p->key);
21338       sm->value = (u8 *) (p->value[0]);
21339     }));
21340     /* *INDENT-ON* */
21341
21342   vec_sort_with_function (sort_me, macro_sort_cmp);
21343
21344   if (vec_len (sort_me))
21345     print (vam->ofp, "%-15s%s", "Name", "Value");
21346   else
21347     print (vam->ofp, "The macro table is empty...");
21348
21349   for (i = 0; i < vec_len (sort_me); i++)
21350     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21351   return 0;
21352 }
21353
21354 static int
21355 dump_node_table (vat_main_t * vam)
21356 {
21357   int i, j;
21358   vlib_node_t *node, *next_node;
21359
21360   if (vec_len (vam->graph_nodes) == 0)
21361     {
21362       print (vam->ofp, "Node table empty, issue get_node_graph...");
21363       return 0;
21364     }
21365
21366   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21367     {
21368       node = vam->graph_nodes[i];
21369       print (vam->ofp, "[%d] %s", i, node->name);
21370       for (j = 0; j < vec_len (node->next_nodes); j++)
21371         {
21372           if (node->next_nodes[j] != ~0)
21373             {
21374               next_node = vam->graph_nodes[node->next_nodes[j]];
21375               print (vam->ofp, "  [%d] %s", j, next_node->name);
21376             }
21377         }
21378     }
21379   return 0;
21380 }
21381
21382 static int
21383 value_sort_cmp (void *a1, void *a2)
21384 {
21385   name_sort_t *n1 = a1;
21386   name_sort_t *n2 = a2;
21387
21388   if (n1->value < n2->value)
21389     return -1;
21390   if (n1->value > n2->value)
21391     return 1;
21392   return 0;
21393 }
21394
21395
21396 static int
21397 dump_msg_api_table (vat_main_t * vam)
21398 {
21399   api_main_t *am = &api_main;
21400   name_sort_t *nses = 0, *ns;
21401   hash_pair_t *hp;
21402   int i;
21403
21404   /* *INDENT-OFF* */
21405   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21406   ({
21407     vec_add2 (nses, ns, 1);
21408     ns->name = (u8 *)(hp->key);
21409     ns->value = (u32) hp->value[0];
21410   }));
21411   /* *INDENT-ON* */
21412
21413   vec_sort_with_function (nses, value_sort_cmp);
21414
21415   for (i = 0; i < vec_len (nses); i++)
21416     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21417   vec_free (nses);
21418   return 0;
21419 }
21420
21421 static int
21422 get_msg_id (vat_main_t * vam)
21423 {
21424   u8 *name_and_crc;
21425   u32 message_index;
21426
21427   if (unformat (vam->input, "%s", &name_and_crc))
21428     {
21429       message_index = vl_api_get_msg_index (name_and_crc);
21430       if (message_index == ~0)
21431         {
21432           print (vam->ofp, " '%s' not found", name_and_crc);
21433           return 0;
21434         }
21435       print (vam->ofp, " '%s' has message index %d",
21436              name_and_crc, message_index);
21437       return 0;
21438     }
21439   errmsg ("name_and_crc required...");
21440   return 0;
21441 }
21442
21443 static int
21444 search_node_table (vat_main_t * vam)
21445 {
21446   unformat_input_t *line_input = vam->input;
21447   u8 *node_to_find;
21448   int j;
21449   vlib_node_t *node, *next_node;
21450   uword *p;
21451
21452   if (vam->graph_node_index_by_name == 0)
21453     {
21454       print (vam->ofp, "Node table empty, issue get_node_graph...");
21455       return 0;
21456     }
21457
21458   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21459     {
21460       if (unformat (line_input, "%s", &node_to_find))
21461         {
21462           vec_add1 (node_to_find, 0);
21463           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21464           if (p == 0)
21465             {
21466               print (vam->ofp, "%s not found...", node_to_find);
21467               goto out;
21468             }
21469           node = vam->graph_nodes[p[0]];
21470           print (vam->ofp, "[%d] %s", p[0], node->name);
21471           for (j = 0; j < vec_len (node->next_nodes); j++)
21472             {
21473               if (node->next_nodes[j] != ~0)
21474                 {
21475                   next_node = vam->graph_nodes[node->next_nodes[j]];
21476                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21477                 }
21478             }
21479         }
21480
21481       else
21482         {
21483           clib_warning ("parse error '%U'", format_unformat_error,
21484                         line_input);
21485           return -99;
21486         }
21487
21488     out:
21489       vec_free (node_to_find);
21490
21491     }
21492
21493   return 0;
21494 }
21495
21496
21497 static int
21498 script (vat_main_t * vam)
21499 {
21500 #if (VPP_API_TEST_BUILTIN==0)
21501   u8 *s = 0;
21502   char *save_current_file;
21503   unformat_input_t save_input;
21504   jmp_buf save_jump_buf;
21505   u32 save_line_number;
21506
21507   FILE *new_fp, *save_ifp;
21508
21509   if (unformat (vam->input, "%s", &s))
21510     {
21511       new_fp = fopen ((char *) s, "r");
21512       if (new_fp == 0)
21513         {
21514           errmsg ("Couldn't open script file %s", s);
21515           vec_free (s);
21516           return -99;
21517         }
21518     }
21519   else
21520     {
21521       errmsg ("Missing script name");
21522       return -99;
21523     }
21524
21525   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21526   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21527   save_ifp = vam->ifp;
21528   save_line_number = vam->input_line_number;
21529   save_current_file = (char *) vam->current_file;
21530
21531   vam->input_line_number = 0;
21532   vam->ifp = new_fp;
21533   vam->current_file = s;
21534   do_one_file (vam);
21535
21536   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21537   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21538   vam->ifp = save_ifp;
21539   vam->input_line_number = save_line_number;
21540   vam->current_file = (u8 *) save_current_file;
21541   vec_free (s);
21542
21543   return 0;
21544 #else
21545   clib_warning ("use the exec command...");
21546   return -99;
21547 #endif
21548 }
21549
21550 static int
21551 echo (vat_main_t * vam)
21552 {
21553   print (vam->ofp, "%v", vam->input->buffer);
21554   return 0;
21555 }
21556
21557 /* List of API message constructors, CLI names map to api_xxx */
21558 #define foreach_vpe_api_msg                                             \
21559 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21560 _(sw_interface_dump,"")                                                 \
21561 _(sw_interface_set_flags,                                               \
21562   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21563 _(sw_interface_add_del_address,                                         \
21564   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21565 _(sw_interface_set_table,                                               \
21566   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21567 _(sw_interface_set_mpls_enable,                                         \
21568   "<intfc> | sw_if_index [disable | dis]")                              \
21569 _(sw_interface_set_vpath,                                               \
21570   "<intfc> | sw_if_index <id> enable | disable")                        \
21571 _(sw_interface_set_vxlan_bypass,                                        \
21572   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21573 _(sw_interface_set_geneve_bypass,                                       \
21574   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21575 _(sw_interface_set_l2_xconnect,                                         \
21576   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21577   "enable | disable")                                                   \
21578 _(sw_interface_set_l2_bridge,                                           \
21579   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21580   "[shg <split-horizon-group>] [bvi]\n"                                 \
21581   "enable | disable")                                                   \
21582 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21583 _(bridge_domain_add_del,                                                \
21584   "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") \
21585 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21586 _(l2fib_add_del,                                                        \
21587   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21588 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21589 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21590 _(l2_flags,                                                             \
21591   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21592 _(bridge_flags,                                                         \
21593   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21594 _(tap_connect,                                                          \
21595   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21596 _(tap_modify,                                                           \
21597   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21598 _(tap_delete,                                                           \
21599   "<vpp-if-name> | sw_if_index <id>")                                   \
21600 _(sw_interface_tap_dump, "")                                            \
21601 _(ip_table_add_del,                                                     \
21602   "table-id <n> [ipv6]\n")                                              \
21603 _(ip_add_del_route,                                                     \
21604   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21605   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21606   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21607   "[multipath] [count <n>]")                                            \
21608 _(ip_mroute_add_del,                                                    \
21609   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21610   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21611 _(mpls_table_add_del,                                                   \
21612   "table-id <n>\n")                                                     \
21613 _(mpls_route_add_del,                                                   \
21614   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21615   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21616   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21617   "[multipath] [count <n>]")                                            \
21618 _(mpls_ip_bind_unbind,                                                  \
21619   "<label> <addr/len>")                                                 \
21620 _(mpls_tunnel_add_del,                                                  \
21621   " via <addr> [table-id <n>]\n"                                        \
21622   "sw_if_index <id>] [l2]  [del]")                                      \
21623 _(proxy_arp_add_del,                                                    \
21624   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21625 _(proxy_arp_intfc_enable_disable,                                       \
21626   "<intfc> | sw_if_index <id> enable | disable")                        \
21627 _(sw_interface_set_unnumbered,                                          \
21628   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21629 _(ip_neighbor_add_del,                                                  \
21630   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21631   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21632 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21633 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21634 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21635   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21636   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21637   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21638 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21639 _(reset_fib, "vrf <n> [ipv6]")                                          \
21640 _(dhcp_proxy_config,                                                    \
21641   "svr <v46-address> src <v46-address>\n"                               \
21642    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21643 _(dhcp_proxy_set_vss,                                                   \
21644   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21645 _(dhcp_proxy_dump, "ip6")                                               \
21646 _(dhcp_client_config,                                                   \
21647   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21648 _(set_ip_flow_hash,                                                     \
21649   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21650 _(sw_interface_ip6_enable_disable,                                      \
21651   "<intfc> | sw_if_index <id> enable | disable")                        \
21652 _(sw_interface_ip6_set_link_local_address,                              \
21653   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21654 _(ip6nd_proxy_add_del,                                                  \
21655   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21656 _(ip6nd_proxy_dump, "")                                                 \
21657 _(sw_interface_ip6nd_ra_prefix,                                         \
21658   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21659   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21660   "[nolink] [isno]")                                                    \
21661 _(sw_interface_ip6nd_ra_config,                                         \
21662   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21663   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21664   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21665 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21666 _(l2_patch_add_del,                                                     \
21667   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21668   "enable | disable")                                                   \
21669 _(sr_localsid_add_del,                                                  \
21670   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21671   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21672 _(classify_add_del_table,                                               \
21673   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21674   " [del] [del-chain] mask <mask-value>\n"                              \
21675   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21676   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21677 _(classify_add_del_session,                                             \
21678   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21679   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21680   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21681   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21682 _(classify_set_interface_ip_table,                                      \
21683   "<intfc> | sw_if_index <nn> table <nn>")                              \
21684 _(classify_set_interface_l2_tables,                                     \
21685   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21686   "  [other-table <nn>]")                                               \
21687 _(get_node_index, "node <node-name")                                    \
21688 _(add_node_next, "node <node-name> next <next-node-name>")              \
21689 _(l2tpv3_create_tunnel,                                                 \
21690   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21691   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21692   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21693 _(l2tpv3_set_tunnel_cookies,                                            \
21694   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21695   "[new_remote_cookie <nn>]\n")                                         \
21696 _(l2tpv3_interface_enable_disable,                                      \
21697   "<intfc> | sw_if_index <nn> enable | disable")                        \
21698 _(l2tpv3_set_lookup_key,                                                \
21699   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21700 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21701 _(vxlan_add_del_tunnel,                                                 \
21702   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21703   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21704   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21705 _(geneve_add_del_tunnel,                                                \
21706   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21707   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21708   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21709 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21710 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21711 _(gre_add_del_tunnel,                                                   \
21712   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21713 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21714 _(l2_fib_clear_table, "")                                               \
21715 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21716 _(l2_interface_vlan_tag_rewrite,                                        \
21717   "<intfc> | sw_if_index <nn> \n"                                       \
21718   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21719   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21720 _(create_vhost_user_if,                                                 \
21721         "socket <filename> [server] [renumber <dev_instance>] "         \
21722         "[mac <mac_address>]")                                          \
21723 _(modify_vhost_user_if,                                                 \
21724         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21725         "[server] [renumber <dev_instance>]")                           \
21726 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21727 _(sw_interface_vhost_user_dump, "")                                     \
21728 _(show_version, "")                                                     \
21729 _(vxlan_gpe_add_del_tunnel,                                             \
21730   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21731   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21732   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21733   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21734 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21735 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21736 _(interface_name_renumber,                                              \
21737   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21738 _(input_acl_set_interface,                                              \
21739   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21740   "  [l2-table <nn>] [del]")                                            \
21741 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21742 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21743 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21744 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21745 _(ip_dump, "ipv4 | ipv6")                                               \
21746 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21747 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21748   "  spid_id <n> ")                                                     \
21749 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21750   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21751   "  integ_alg <alg> integ_key <hex>")                                  \
21752 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21753   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21754   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21755   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21756 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21757 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21758   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21759   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21760   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21761 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21762 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21763   "  <alg> <hex>\n")                                                    \
21764 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21765 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21766 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21767   "(auth_data 0x<data> | auth_data <data>)")                            \
21768 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21769   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21770 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21771   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21772   "(local|remote)")                                                     \
21773 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21774 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21775 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21776 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21777 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21778 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21779 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21780 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21781 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21782 _(delete_loopback,"sw_if_index <nn>")                                   \
21783 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21784 _(map_add_domain,                                                       \
21785   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21786   "ip6-src <ip6addr> "                                                  \
21787   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21788 _(map_del_domain, "index <n>")                                          \
21789 _(map_add_del_rule,                                                     \
21790   "index <n> psid <n> dst <ip6addr> [del]")                             \
21791 _(map_domain_dump, "")                                                  \
21792 _(map_rule_dump, "index <map-domain>")                                  \
21793 _(want_interface_events,  "enable|disable")                             \
21794 _(want_stats,"enable|disable")                                          \
21795 _(get_first_msg_id, "client <name>")                                    \
21796 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21797 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21798   "fib-id <nn> [ip4][ip6][default]")                                    \
21799 _(get_node_graph, " ")                                                  \
21800 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21801 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21802 _(ioam_disable, "")                                                     \
21803 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21804                             " sw_if_index <sw_if_index> p <priority> "  \
21805                             "w <weight>] [del]")                        \
21806 _(one_add_del_locator, "locator-set <locator_name> "                    \
21807                         "iface <intf> | sw_if_index <sw_if_index> "     \
21808                         "p <priority> w <weight> [del]")                \
21809 _(one_add_del_local_eid,"vni <vni> eid "                                \
21810                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21811                          "locator-set <locator_name> [del]"             \
21812                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21813 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21814 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21815 _(one_enable_disable, "enable|disable")                                 \
21816 _(one_map_register_enable_disable, "enable|disable")                    \
21817 _(one_map_register_fallback_threshold, "<value>")                       \
21818 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21819 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21820                                "[seid <seid>] "                         \
21821                                "rloc <locator> p <prio> "               \
21822                                "w <weight> [rloc <loc> ... ] "          \
21823                                "action <action> [del-all]")             \
21824 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21825                           "<local-eid>")                                \
21826 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21827 _(one_use_petr, "ip-address> | disable")                                \
21828 _(one_map_request_mode, "src-dst|dst-only")                             \
21829 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21830 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21831 _(one_locator_set_dump, "[local | remote]")                             \
21832 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21833 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21834                        "[local] | [remote]")                            \
21835 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21836 _(one_ndp_bd_get, "")                                                   \
21837 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21838 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21839 _(one_l2_arp_bd_get, "")                                                \
21840 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21841 _(one_stats_enable_disable, "enable|disalbe")                           \
21842 _(show_one_stats_enable_disable, "")                                    \
21843 _(one_eid_table_vni_dump, "")                                           \
21844 _(one_eid_table_map_dump, "l2|l3")                                      \
21845 _(one_map_resolver_dump, "")                                            \
21846 _(one_map_server_dump, "")                                              \
21847 _(one_adjacencies_get, "vni <vni>")                                     \
21848 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21849 _(show_one_rloc_probe_state, "")                                        \
21850 _(show_one_map_register_state, "")                                      \
21851 _(show_one_status, "")                                                  \
21852 _(one_stats_dump, "")                                                   \
21853 _(one_stats_flush, "")                                                  \
21854 _(one_get_map_request_itr_rlocs, "")                                    \
21855 _(one_map_register_set_ttl, "<ttl>")                                    \
21856 _(one_set_transport_protocol, "udp|api")                                \
21857 _(one_get_transport_protocol, "")                                       \
21858 _(show_one_nsh_mapping, "")                                             \
21859 _(show_one_pitr, "")                                                    \
21860 _(show_one_use_petr, "")                                                \
21861 _(show_one_map_request_mode, "")                                        \
21862 _(show_one_map_register_ttl, "")                                        \
21863 _(show_one_map_register_fallback_threshold, "")                         \
21864 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21865                             " sw_if_index <sw_if_index> p <priority> "  \
21866                             "w <weight>] [del]")                        \
21867 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21868                         "iface <intf> | sw_if_index <sw_if_index> "     \
21869                         "p <priority> w <weight> [del]")                \
21870 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21871                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21872                          "locator-set <locator_name> [del]"             \
21873                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21874 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21875 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21876 _(lisp_enable_disable, "enable|disable")                                \
21877 _(lisp_map_register_enable_disable, "enable|disable")                   \
21878 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21879 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21880                                "[seid <seid>] "                         \
21881                                "rloc <locator> p <prio> "               \
21882                                "w <weight> [rloc <loc> ... ] "          \
21883                                "action <action> [del-all]")             \
21884 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21885                           "<local-eid>")                                \
21886 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21887 _(lisp_use_petr, "<ip-address> | disable")                              \
21888 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21889 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21890 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21891 _(lisp_locator_set_dump, "[local | remote]")                            \
21892 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21893 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21894                        "[local] | [remote]")                            \
21895 _(lisp_eid_table_vni_dump, "")                                          \
21896 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21897 _(lisp_map_resolver_dump, "")                                           \
21898 _(lisp_map_server_dump, "")                                             \
21899 _(lisp_adjacencies_get, "vni <vni>")                                    \
21900 _(gpe_fwd_entry_vnis_get, "")                                           \
21901 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21902 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21903                                 "[table <table-id>]")                   \
21904 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21905 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21906 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21907 _(gpe_get_encap_mode, "")                                               \
21908 _(lisp_gpe_add_del_iface, "up|down")                                    \
21909 _(lisp_gpe_enable_disable, "enable|disable")                            \
21910 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21911   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21912 _(show_lisp_rloc_probe_state, "")                                       \
21913 _(show_lisp_map_register_state, "")                                     \
21914 _(show_lisp_status, "")                                                 \
21915 _(lisp_get_map_request_itr_rlocs, "")                                   \
21916 _(show_lisp_pitr, "")                                                   \
21917 _(show_lisp_use_petr, "")                                               \
21918 _(show_lisp_map_request_mode, "")                                       \
21919 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21920 _(af_packet_delete, "name <host interface name>")                       \
21921 _(policer_add_del, "name <policer name> <params> [del]")                \
21922 _(policer_dump, "[name <policer name>]")                                \
21923 _(policer_classify_set_interface,                                       \
21924   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21925   "  [l2-table <nn>] [del]")                                            \
21926 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21927 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21928     "[master|slave]")                                                   \
21929 _(netmap_delete, "name <interface name>")                               \
21930 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21931 _(mpls_fib_dump, "")                                                    \
21932 _(classify_table_ids, "")                                               \
21933 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21934 _(classify_table_info, "table_id <nn>")                                 \
21935 _(classify_session_dump, "table_id <nn>")                               \
21936 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21937     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21938     "[template_interval <nn>] [udp_checksum]")                          \
21939 _(ipfix_exporter_dump, "")                                              \
21940 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21941 _(ipfix_classify_stream_dump, "")                                       \
21942 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21943 _(ipfix_classify_table_dump, "")                                        \
21944 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21945 _(sw_interface_span_dump, "[l2]")                                           \
21946 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21947 _(pg_create_interface, "if_id <nn>")                                    \
21948 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21949 _(pg_enable_disable, "[stream <id>] disable")                           \
21950 _(ip_source_and_port_range_check_add_del,                               \
21951   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21952 _(ip_source_and_port_range_check_interface_add_del,                     \
21953   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21954   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21955 _(ipsec_gre_add_del_tunnel,                                             \
21956   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21957 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21958 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21959 _(l2_interface_pbb_tag_rewrite,                                         \
21960   "<intfc> | sw_if_index <nn> \n"                                       \
21961   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21962   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21963 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21964 _(flow_classify_set_interface,                                          \
21965   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21966 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21967 _(ip_fib_dump, "")                                                      \
21968 _(ip_mfib_dump, "")                                                     \
21969 _(ip6_fib_dump, "")                                                     \
21970 _(ip6_mfib_dump, "")                                                    \
21971 _(feature_enable_disable, "arc_name <arc_name> "                        \
21972   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21973 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21974 "[disable]")                                                            \
21975 _(l2_xconnect_dump, "")                                                 \
21976 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21977 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21978 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21979 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21980 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21981 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21982 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21983   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21984 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21985 _(memfd_segment_create,"size <nnn>")                                    \
21986 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21987 _(dns_enable_disable, "[enable][disable]")                              \
21988 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21989 _(dns_resolve_name, "<hostname>")                                       \
21990 _(dns_resolve_ip, "<ip4|ip6>")
21991
21992 /* List of command functions, CLI names map directly to functions */
21993 #define foreach_cli_function                                    \
21994 _(comment, "usage: comment <ignore-rest-of-line>")              \
21995 _(dump_interface_table, "usage: dump_interface_table")          \
21996 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21997 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21998 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21999 _(dump_stats_table, "usage: dump_stats_table")                  \
22000 _(dump_macro_table, "usage: dump_macro_table ")                 \
22001 _(dump_node_table, "usage: dump_node_table")                    \
22002 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22003 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22004 _(echo, "usage: echo <message>")                                \
22005 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22006 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22007 _(help, "usage: help")                                          \
22008 _(q, "usage: quit")                                             \
22009 _(quit, "usage: quit")                                          \
22010 _(search_node_table, "usage: search_node_table <name>...")      \
22011 _(set, "usage: set <variable-name> <value>")                    \
22012 _(script, "usage: script <file-name>")                          \
22013 _(unset, "usage: unset <variable-name>")
22014 #define _(N,n)                                  \
22015     static void vl_api_##n##_t_handler_uni      \
22016     (vl_api_##n##_t * mp)                       \
22017     {                                           \
22018         vat_main_t * vam = &vat_main;           \
22019         if (vam->json_output) {                 \
22020             vl_api_##n##_t_handler_json(mp);    \
22021         } else {                                \
22022             vl_api_##n##_t_handler(mp);         \
22023         }                                       \
22024     }
22025 foreach_vpe_api_reply_msg;
22026 #if VPP_API_TEST_BUILTIN == 0
22027 foreach_standalone_reply_msg;
22028 #endif
22029 #undef _
22030
22031 void
22032 vat_api_hookup (vat_main_t * vam)
22033 {
22034 #define _(N,n)                                                  \
22035     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22036                            vl_api_##n##_t_handler_uni,          \
22037                            vl_noop_handler,                     \
22038                            vl_api_##n##_t_endian,               \
22039                            vl_api_##n##_t_print,                \
22040                            sizeof(vl_api_##n##_t), 1);
22041   foreach_vpe_api_reply_msg;
22042 #if VPP_API_TEST_BUILTIN == 0
22043   foreach_standalone_reply_msg;
22044 #endif
22045 #undef _
22046
22047 #if (VPP_API_TEST_BUILTIN==0)
22048   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22049
22050   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22051
22052   vam->function_by_name = hash_create_string (0, sizeof (uword));
22053
22054   vam->help_by_name = hash_create_string (0, sizeof (uword));
22055 #endif
22056
22057   /* API messages we can send */
22058 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22059   foreach_vpe_api_msg;
22060 #undef _
22061
22062   /* Help strings */
22063 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22064   foreach_vpe_api_msg;
22065 #undef _
22066
22067   /* CLI functions */
22068 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22069   foreach_cli_function;
22070 #undef _
22071
22072   /* Help strings */
22073 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22074   foreach_cli_function;
22075 #undef _
22076 }
22077
22078 #if VPP_API_TEST_BUILTIN
22079 static clib_error_t *
22080 vat_api_hookup_shim (vlib_main_t * vm)
22081 {
22082   vat_api_hookup (&vat_main);
22083   return 0;
22084 }
22085
22086 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22087 #endif
22088
22089 /*
22090  * fd.io coding-style-patch-verification: ON
22091  *
22092  * Local Variables:
22093  * eval: (c-set-style "gnu")
22094  * End:
22095  */