Add reverse DNS (ip to name) resolution
[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 _(ikev2_profile_add_del_reply)                          \
5111 _(ikev2_profile_set_auth_reply)                         \
5112 _(ikev2_profile_set_id_reply)                           \
5113 _(ikev2_profile_set_ts_reply)                           \
5114 _(ikev2_set_local_key_reply)                            \
5115 _(ikev2_set_responder_reply)                            \
5116 _(ikev2_set_ike_transforms_reply)                       \
5117 _(ikev2_set_esp_transforms_reply)                       \
5118 _(ikev2_set_sa_lifetime_reply)                          \
5119 _(ikev2_initiate_sa_init_reply)                         \
5120 _(ikev2_initiate_del_ike_sa_reply)                      \
5121 _(ikev2_initiate_del_child_sa_reply)                    \
5122 _(ikev2_initiate_rekey_child_sa_reply)                  \
5123 _(delete_loopback_reply)                                \
5124 _(bd_ip_mac_add_del_reply)                              \
5125 _(map_del_domain_reply)                                 \
5126 _(map_add_del_rule_reply)                               \
5127 _(want_interface_events_reply)                          \
5128 _(want_stats_reply)                                     \
5129 _(cop_interface_enable_disable_reply)                   \
5130 _(cop_whitelist_enable_disable_reply)                   \
5131 _(sw_interface_clear_stats_reply)                       \
5132 _(ioam_enable_reply)                                    \
5133 _(ioam_disable_reply)                                   \
5134 _(one_add_del_locator_reply)                            \
5135 _(one_add_del_local_eid_reply)                          \
5136 _(one_add_del_remote_mapping_reply)                     \
5137 _(one_add_del_adjacency_reply)                          \
5138 _(one_add_del_map_resolver_reply)                       \
5139 _(one_add_del_map_server_reply)                         \
5140 _(one_enable_disable_reply)                             \
5141 _(one_rloc_probe_enable_disable_reply)                  \
5142 _(one_map_register_enable_disable_reply)                \
5143 _(one_map_register_set_ttl_reply)                       \
5144 _(one_set_transport_protocol_reply)                     \
5145 _(one_map_register_fallback_threshold_reply)            \
5146 _(one_pitr_set_locator_set_reply)                       \
5147 _(one_map_request_mode_reply)                           \
5148 _(one_add_del_map_request_itr_rlocs_reply)              \
5149 _(one_eid_table_add_del_map_reply)                      \
5150 _(one_use_petr_reply)                                   \
5151 _(one_stats_enable_disable_reply)                       \
5152 _(one_add_del_l2_arp_entry_reply)                       \
5153 _(one_add_del_ndp_entry_reply)                          \
5154 _(one_stats_flush_reply)                                \
5155 _(gpe_enable_disable_reply)                             \
5156 _(gpe_set_encap_mode_reply)                             \
5157 _(gpe_add_del_iface_reply)                              \
5158 _(gpe_add_del_native_fwd_rpath_reply)                   \
5159 _(af_packet_delete_reply)                               \
5160 _(policer_classify_set_interface_reply)                 \
5161 _(netmap_create_reply)                                  \
5162 _(netmap_delete_reply)                                  \
5163 _(set_ipfix_exporter_reply)                             \
5164 _(set_ipfix_classify_stream_reply)                      \
5165 _(ipfix_classify_table_add_del_reply)                   \
5166 _(flow_classify_set_interface_reply)                    \
5167 _(sw_interface_span_enable_disable_reply)               \
5168 _(pg_capture_reply)                                     \
5169 _(pg_enable_disable_reply)                              \
5170 _(ip_source_and_port_range_check_add_del_reply)         \
5171 _(ip_source_and_port_range_check_interface_add_del_reply)\
5172 _(delete_subif_reply)                                   \
5173 _(l2_interface_pbb_tag_rewrite_reply)                   \
5174 _(punt_reply)                                           \
5175 _(feature_enable_disable_reply)                         \
5176 _(sw_interface_tag_add_del_reply)                       \
5177 _(sw_interface_set_mtu_reply)                           \
5178 _(p2p_ethernet_add_reply)                               \
5179 _(p2p_ethernet_del_reply)                               \
5180 _(lldp_config_reply)                                    \
5181 _(sw_interface_set_lldp_reply)                          \
5182 _(tcp_configure_src_addresses_reply)                    \
5183 _(app_namespace_add_del_reply)                          \
5184 _(dns_enable_disable_reply)                             \
5185 _(dns_name_server_add_del_reply)
5186
5187 #define _(n)                                    \
5188     static void vl_api_##n##_t_handler          \
5189     (vl_api_##n##_t * mp)                       \
5190     {                                           \
5191         vat_main_t * vam = &vat_main;           \
5192         i32 retval = ntohl(mp->retval);         \
5193         if (vam->async_mode) {                  \
5194             vam->async_errors += (retval < 0);  \
5195         } else {                                \
5196             vam->retval = retval;               \
5197             vam->result_ready = 1;              \
5198         }                                       \
5199     }
5200 foreach_standard_reply_retval_handler;
5201 #undef _
5202
5203 #define _(n)                                    \
5204     static void vl_api_##n##_t_handler_json     \
5205     (vl_api_##n##_t * mp)                       \
5206     {                                           \
5207         vat_main_t * vam = &vat_main;           \
5208         vat_json_node_t node;                   \
5209         vat_json_init_object(&node);            \
5210         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5211         vat_json_print(vam->ofp, &node);        \
5212         vam->retval = ntohl(mp->retval);        \
5213         vam->result_ready = 1;                  \
5214     }
5215 foreach_standard_reply_retval_handler;
5216 #undef _
5217
5218 /*
5219  * Table of message reply handlers, must include boilerplate handlers
5220  * we just generated
5221  */
5222
5223 #define foreach_vpe_api_reply_msg                                       \
5224 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5225 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5226 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5227 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5228 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5229 _(CLI_REPLY, cli_reply)                                                 \
5230 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5231 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5232   sw_interface_add_del_address_reply)                                   \
5233 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5234 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5235 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5236 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5237 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5238 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5239 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5240   sw_interface_set_l2_xconnect_reply)                                   \
5241 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5242   sw_interface_set_l2_bridge_reply)                                     \
5243 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5244 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5245 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5246 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5247 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5248 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5249 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5250 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5251 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5252 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5253 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5254 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5255 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5256 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5257 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5258 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5259 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5260 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5261 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5262 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5263   proxy_arp_intfc_enable_disable_reply)                                 \
5264 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5265 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5266   sw_interface_set_unnumbered_reply)                                    \
5267 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5268 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5269 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5270 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5271 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5272 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5273 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5274 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5275 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5276 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5277 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5278 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5279   sw_interface_ip6_enable_disable_reply)                                \
5280 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5281   sw_interface_ip6_set_link_local_address_reply)                        \
5282 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5283 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5284 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5285   sw_interface_ip6nd_ra_prefix_reply)                                   \
5286 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5287   sw_interface_ip6nd_ra_config_reply)                                   \
5288 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5289 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5290 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5291 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5292 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5293 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5294 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5295 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5296 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5297 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5298 classify_set_interface_ip_table_reply)                                  \
5299 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5300   classify_set_interface_l2_tables_reply)                               \
5301 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5302 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5303 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5304 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5305 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5306   l2tpv3_interface_enable_disable_reply)                                \
5307 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5308 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5309 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5310 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5311 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5312 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5313 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5314 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5315 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5316 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5317 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5318 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5319 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5320 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5321 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5322 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5323 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5324 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5325 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5326 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5327 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5328 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5329 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5330 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5331 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5332 _(L2_MACS_EVENT, l2_macs_event)                                         \
5333 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5334 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5335 _(IP_DETAILS, ip_details)                                               \
5336 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5337 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5338 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5339 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5340 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5341 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5342 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5343 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5344 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5345 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5346 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5347 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5348 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5349 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5350 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5351 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5352 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5353 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5354 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5355 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5356 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5357 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5358 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5359 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5360 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5361 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5362 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5363 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5364 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5365 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5366 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5367 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5368 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5369 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5370 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5371 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5372 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5373 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5374 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5375 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5376 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5377 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5378 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5379 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5380 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5381 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5382 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5383   one_map_register_enable_disable_reply)                                \
5384 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5385 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5386 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5387 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5388   one_map_register_fallback_threshold_reply)                            \
5389 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5390   one_rloc_probe_enable_disable_reply)                                  \
5391 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5392 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5393 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5394 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5395 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5396 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5397 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5398 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5399 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5400 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5401 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5402 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5403 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5404 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5405 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5406 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5407   show_one_stats_enable_disable_reply)                                  \
5408 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5409 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5410 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5411 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5412 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5413 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5414 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5415 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5416 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5417 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5418 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5419 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5420 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5421 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5422 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5423   gpe_add_del_native_fwd_rpath_reply)                                   \
5424 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5425   gpe_fwd_entry_path_details)                                           \
5426 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5427 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5428   one_add_del_map_request_itr_rlocs_reply)                              \
5429 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5430   one_get_map_request_itr_rlocs_reply)                                  \
5431 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5432 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5433 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5434 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5435 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5436 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5437   show_one_map_register_state_reply)                                    \
5438 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5439 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5440   show_one_map_register_fallback_threshold_reply)                       \
5441 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5442 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5443 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5444 _(POLICER_DETAILS, policer_details)                                     \
5445 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5446 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5447 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5448 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5449 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5450 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5451 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5452 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5453 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5454 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5455 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5456 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5457 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5458 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5459 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5460 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5461 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5462 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5463 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5464 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5465 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5466 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5467 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5468 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5469 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5470  ip_source_and_port_range_check_add_del_reply)                          \
5471 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5472  ip_source_and_port_range_check_interface_add_del_reply)                \
5473 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5474 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5475 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5476 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5477 _(PUNT_REPLY, punt_reply)                                               \
5478 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5479 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5480 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5481 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5482 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5483 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5484 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5485 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5486 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5487 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5488 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5489 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5490 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5491 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5492 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5493 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5494 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5495 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)
5496
5497 #define foreach_standalone_reply_msg                                    \
5498 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5499 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5500 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5501 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5502 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5503 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5504 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5505 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5506
5507 typedef struct
5508 {
5509   u8 *name;
5510   u32 value;
5511 } name_sort_t;
5512
5513
5514 #define STR_VTR_OP_CASE(op)     \
5515     case L2_VTR_ ## op:         \
5516         return "" # op;
5517
5518 static const char *
5519 str_vtr_op (u32 vtr_op)
5520 {
5521   switch (vtr_op)
5522     {
5523       STR_VTR_OP_CASE (DISABLED);
5524       STR_VTR_OP_CASE (PUSH_1);
5525       STR_VTR_OP_CASE (PUSH_2);
5526       STR_VTR_OP_CASE (POP_1);
5527       STR_VTR_OP_CASE (POP_2);
5528       STR_VTR_OP_CASE (TRANSLATE_1_1);
5529       STR_VTR_OP_CASE (TRANSLATE_1_2);
5530       STR_VTR_OP_CASE (TRANSLATE_2_1);
5531       STR_VTR_OP_CASE (TRANSLATE_2_2);
5532     }
5533
5534   return "UNKNOWN";
5535 }
5536
5537 static int
5538 dump_sub_interface_table (vat_main_t * vam)
5539 {
5540   const sw_interface_subif_t *sub = NULL;
5541
5542   if (vam->json_output)
5543     {
5544       clib_warning
5545         ("JSON output supported only for VPE API calls and dump_stats_table");
5546       return -99;
5547     }
5548
5549   print (vam->ofp,
5550          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5551          "Interface", "sw_if_index",
5552          "sub id", "dot1ad", "tags", "outer id",
5553          "inner id", "exact", "default", "outer any", "inner any");
5554
5555   vec_foreach (sub, vam->sw_if_subif_table)
5556   {
5557     print (vam->ofp,
5558            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5559            sub->interface_name,
5560            sub->sw_if_index,
5561            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5562            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5563            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5564            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5565     if (sub->vtr_op != L2_VTR_DISABLED)
5566       {
5567         print (vam->ofp,
5568                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5569                "tag1: %d tag2: %d ]",
5570                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5571                sub->vtr_tag1, sub->vtr_tag2);
5572       }
5573   }
5574
5575   return 0;
5576 }
5577
5578 static int
5579 name_sort_cmp (void *a1, void *a2)
5580 {
5581   name_sort_t *n1 = a1;
5582   name_sort_t *n2 = a2;
5583
5584   return strcmp ((char *) n1->name, (char *) n2->name);
5585 }
5586
5587 static int
5588 dump_interface_table (vat_main_t * vam)
5589 {
5590   hash_pair_t *p;
5591   name_sort_t *nses = 0, *ns;
5592
5593   if (vam->json_output)
5594     {
5595       clib_warning
5596         ("JSON output supported only for VPE API calls and dump_stats_table");
5597       return -99;
5598     }
5599
5600   /* *INDENT-OFF* */
5601   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5602   ({
5603     vec_add2 (nses, ns, 1);
5604     ns->name = (u8 *)(p->key);
5605     ns->value = (u32) p->value[0];
5606   }));
5607   /* *INDENT-ON* */
5608
5609   vec_sort_with_function (nses, name_sort_cmp);
5610
5611   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5612   vec_foreach (ns, nses)
5613   {
5614     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5615   }
5616   vec_free (nses);
5617   return 0;
5618 }
5619
5620 static int
5621 dump_ip_table (vat_main_t * vam, int is_ipv6)
5622 {
5623   const ip_details_t *det = NULL;
5624   const ip_address_details_t *address = NULL;
5625   u32 i = ~0;
5626
5627   print (vam->ofp, "%-12s", "sw_if_index");
5628
5629   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5630   {
5631     i++;
5632     if (!det->present)
5633       {
5634         continue;
5635       }
5636     print (vam->ofp, "%-12d", i);
5637     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5638     if (!det->addr)
5639       {
5640         continue;
5641       }
5642     vec_foreach (address, det->addr)
5643     {
5644       print (vam->ofp,
5645              "            %-30U%-13d",
5646              is_ipv6 ? format_ip6_address : format_ip4_address,
5647              address->ip, address->prefix_length);
5648     }
5649   }
5650
5651   return 0;
5652 }
5653
5654 static int
5655 dump_ipv4_table (vat_main_t * vam)
5656 {
5657   if (vam->json_output)
5658     {
5659       clib_warning
5660         ("JSON output supported only for VPE API calls and dump_stats_table");
5661       return -99;
5662     }
5663
5664   return dump_ip_table (vam, 0);
5665 }
5666
5667 static int
5668 dump_ipv6_table (vat_main_t * vam)
5669 {
5670   if (vam->json_output)
5671     {
5672       clib_warning
5673         ("JSON output supported only for VPE API calls and dump_stats_table");
5674       return -99;
5675     }
5676
5677   return dump_ip_table (vam, 1);
5678 }
5679
5680 static char *
5681 counter_type_to_str (u8 counter_type, u8 is_combined)
5682 {
5683   if (!is_combined)
5684     {
5685       switch (counter_type)
5686         {
5687         case VNET_INTERFACE_COUNTER_DROP:
5688           return "drop";
5689         case VNET_INTERFACE_COUNTER_PUNT:
5690           return "punt";
5691         case VNET_INTERFACE_COUNTER_IP4:
5692           return "ip4";
5693         case VNET_INTERFACE_COUNTER_IP6:
5694           return "ip6";
5695         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5696           return "rx-no-buf";
5697         case VNET_INTERFACE_COUNTER_RX_MISS:
5698           return "rx-miss";
5699         case VNET_INTERFACE_COUNTER_RX_ERROR:
5700           return "rx-error";
5701         case VNET_INTERFACE_COUNTER_TX_ERROR:
5702           return "tx-error";
5703         default:
5704           return "INVALID-COUNTER-TYPE";
5705         }
5706     }
5707   else
5708     {
5709       switch (counter_type)
5710         {
5711         case VNET_INTERFACE_COUNTER_RX:
5712           return "rx";
5713         case VNET_INTERFACE_COUNTER_TX:
5714           return "tx";
5715         default:
5716           return "INVALID-COUNTER-TYPE";
5717         }
5718     }
5719 }
5720
5721 static int
5722 dump_stats_table (vat_main_t * vam)
5723 {
5724   vat_json_node_t node;
5725   vat_json_node_t *msg_array;
5726   vat_json_node_t *msg;
5727   vat_json_node_t *counter_array;
5728   vat_json_node_t *counter;
5729   interface_counter_t c;
5730   u64 packets;
5731   ip4_fib_counter_t *c4;
5732   ip6_fib_counter_t *c6;
5733   ip4_nbr_counter_t *n4;
5734   ip6_nbr_counter_t *n6;
5735   int i, j;
5736
5737   if (!vam->json_output)
5738     {
5739       clib_warning ("dump_stats_table supported only in JSON format");
5740       return -99;
5741     }
5742
5743   vat_json_init_object (&node);
5744
5745   /* interface counters */
5746   msg_array = vat_json_object_add (&node, "interface_counters");
5747   vat_json_init_array (msg_array);
5748   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5749     {
5750       msg = vat_json_array_add (msg_array);
5751       vat_json_init_object (msg);
5752       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5753                                        (u8 *) counter_type_to_str (i, 0));
5754       vat_json_object_add_int (msg, "is_combined", 0);
5755       counter_array = vat_json_object_add (msg, "data");
5756       vat_json_init_array (counter_array);
5757       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5758         {
5759           packets = vam->simple_interface_counters[i][j];
5760           vat_json_array_add_uint (counter_array, packets);
5761         }
5762     }
5763   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5764     {
5765       msg = vat_json_array_add (msg_array);
5766       vat_json_init_object (msg);
5767       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5768                                        (u8 *) counter_type_to_str (i, 1));
5769       vat_json_object_add_int (msg, "is_combined", 1);
5770       counter_array = vat_json_object_add (msg, "data");
5771       vat_json_init_array (counter_array);
5772       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5773         {
5774           c = vam->combined_interface_counters[i][j];
5775           counter = vat_json_array_add (counter_array);
5776           vat_json_init_object (counter);
5777           vat_json_object_add_uint (counter, "packets", c.packets);
5778           vat_json_object_add_uint (counter, "bytes", c.bytes);
5779         }
5780     }
5781
5782   /* ip4 fib counters */
5783   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5784   vat_json_init_array (msg_array);
5785   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5786     {
5787       msg = vat_json_array_add (msg_array);
5788       vat_json_init_object (msg);
5789       vat_json_object_add_uint (msg, "vrf_id",
5790                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5791       counter_array = vat_json_object_add (msg, "c");
5792       vat_json_init_array (counter_array);
5793       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5794         {
5795           counter = vat_json_array_add (counter_array);
5796           vat_json_init_object (counter);
5797           c4 = &vam->ip4_fib_counters[i][j];
5798           vat_json_object_add_ip4 (counter, "address", c4->address);
5799           vat_json_object_add_uint (counter, "address_length",
5800                                     c4->address_length);
5801           vat_json_object_add_uint (counter, "packets", c4->packets);
5802           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5803         }
5804     }
5805
5806   /* ip6 fib counters */
5807   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5808   vat_json_init_array (msg_array);
5809   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5810     {
5811       msg = vat_json_array_add (msg_array);
5812       vat_json_init_object (msg);
5813       vat_json_object_add_uint (msg, "vrf_id",
5814                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5815       counter_array = vat_json_object_add (msg, "c");
5816       vat_json_init_array (counter_array);
5817       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5818         {
5819           counter = vat_json_array_add (counter_array);
5820           vat_json_init_object (counter);
5821           c6 = &vam->ip6_fib_counters[i][j];
5822           vat_json_object_add_ip6 (counter, "address", c6->address);
5823           vat_json_object_add_uint (counter, "address_length",
5824                                     c6->address_length);
5825           vat_json_object_add_uint (counter, "packets", c6->packets);
5826           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5827         }
5828     }
5829
5830   /* ip4 nbr counters */
5831   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5832   vat_json_init_array (msg_array);
5833   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5834     {
5835       msg = vat_json_array_add (msg_array);
5836       vat_json_init_object (msg);
5837       vat_json_object_add_uint (msg, "sw_if_index", i);
5838       counter_array = vat_json_object_add (msg, "c");
5839       vat_json_init_array (counter_array);
5840       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5841         {
5842           counter = vat_json_array_add (counter_array);
5843           vat_json_init_object (counter);
5844           n4 = &vam->ip4_nbr_counters[i][j];
5845           vat_json_object_add_ip4 (counter, "address", n4->address);
5846           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5847           vat_json_object_add_uint (counter, "packets", n4->packets);
5848           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5849         }
5850     }
5851
5852   /* ip6 nbr counters */
5853   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5854   vat_json_init_array (msg_array);
5855   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5856     {
5857       msg = vat_json_array_add (msg_array);
5858       vat_json_init_object (msg);
5859       vat_json_object_add_uint (msg, "sw_if_index", i);
5860       counter_array = vat_json_object_add (msg, "c");
5861       vat_json_init_array (counter_array);
5862       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5863         {
5864           counter = vat_json_array_add (counter_array);
5865           vat_json_init_object (counter);
5866           n6 = &vam->ip6_nbr_counters[i][j];
5867           vat_json_object_add_ip6 (counter, "address", n6->address);
5868           vat_json_object_add_uint (counter, "packets", n6->packets);
5869           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5870         }
5871     }
5872
5873   vat_json_print (vam->ofp, &node);
5874   vat_json_free (&node);
5875
5876   return 0;
5877 }
5878
5879 /*
5880  * Pass CLI buffers directly in the CLI_INBAND API message,
5881  * instead of an additional shared memory area.
5882  */
5883 static int
5884 exec_inband (vat_main_t * vam)
5885 {
5886   vl_api_cli_inband_t *mp;
5887   unformat_input_t *i = vam->input;
5888   int ret;
5889
5890   if (vec_len (i->buffer) == 0)
5891     return -1;
5892
5893   if (vam->exec_mode == 0 && unformat (i, "mode"))
5894     {
5895       vam->exec_mode = 1;
5896       return 0;
5897     }
5898   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5899     {
5900       vam->exec_mode = 0;
5901       return 0;
5902     }
5903
5904   /*
5905    * In order for the CLI command to work, it
5906    * must be a vector ending in \n, not a C-string ending
5907    * in \n\0.
5908    */
5909   u32 len = vec_len (vam->input->buffer);
5910   M2 (CLI_INBAND, mp, len);
5911   clib_memcpy (mp->cmd, vam->input->buffer, len);
5912   mp->length = htonl (len);
5913
5914   S (mp);
5915   W (ret);
5916   /* json responses may or may not include a useful reply... */
5917   if (vec_len (vam->cmd_reply))
5918     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5919   return ret;
5920 }
5921
5922 int
5923 exec (vat_main_t * vam)
5924 {
5925   return exec_inband (vam);
5926 }
5927
5928 static int
5929 api_create_loopback (vat_main_t * vam)
5930 {
5931   unformat_input_t *i = vam->input;
5932   vl_api_create_loopback_t *mp;
5933   vl_api_create_loopback_instance_t *mp_lbi;
5934   u8 mac_address[6];
5935   u8 mac_set = 0;
5936   u8 is_specified = 0;
5937   u32 user_instance = 0;
5938   int ret;
5939
5940   memset (mac_address, 0, sizeof (mac_address));
5941
5942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943     {
5944       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5945         mac_set = 1;
5946       if (unformat (i, "instance %d", &user_instance))
5947         is_specified = 1;
5948       else
5949         break;
5950     }
5951
5952   if (is_specified)
5953     {
5954       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5955       mp_lbi->is_specified = is_specified;
5956       if (is_specified)
5957         mp_lbi->user_instance = htonl (user_instance);
5958       if (mac_set)
5959         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5960       S (mp_lbi);
5961     }
5962   else
5963     {
5964       /* Construct the API message */
5965       M (CREATE_LOOPBACK, mp);
5966       if (mac_set)
5967         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5968       S (mp);
5969     }
5970
5971   W (ret);
5972   return ret;
5973 }
5974
5975 static int
5976 api_delete_loopback (vat_main_t * vam)
5977 {
5978   unformat_input_t *i = vam->input;
5979   vl_api_delete_loopback_t *mp;
5980   u32 sw_if_index = ~0;
5981   int ret;
5982
5983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5984     {
5985       if (unformat (i, "sw_if_index %d", &sw_if_index))
5986         ;
5987       else
5988         break;
5989     }
5990
5991   if (sw_if_index == ~0)
5992     {
5993       errmsg ("missing sw_if_index");
5994       return -99;
5995     }
5996
5997   /* Construct the API message */
5998   M (DELETE_LOOPBACK, mp);
5999   mp->sw_if_index = ntohl (sw_if_index);
6000
6001   S (mp);
6002   W (ret);
6003   return ret;
6004 }
6005
6006 static int
6007 api_want_stats (vat_main_t * vam)
6008 {
6009   unformat_input_t *i = vam->input;
6010   vl_api_want_stats_t *mp;
6011   int enable = -1;
6012   int ret;
6013
6014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6015     {
6016       if (unformat (i, "enable"))
6017         enable = 1;
6018       else if (unformat (i, "disable"))
6019         enable = 0;
6020       else
6021         break;
6022     }
6023
6024   if (enable == -1)
6025     {
6026       errmsg ("missing enable|disable");
6027       return -99;
6028     }
6029
6030   M (WANT_STATS, mp);
6031   mp->enable_disable = enable;
6032
6033   S (mp);
6034   W (ret);
6035   return ret;
6036 }
6037
6038 static int
6039 api_want_interface_events (vat_main_t * vam)
6040 {
6041   unformat_input_t *i = vam->input;
6042   vl_api_want_interface_events_t *mp;
6043   int enable = -1;
6044   int ret;
6045
6046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6047     {
6048       if (unformat (i, "enable"))
6049         enable = 1;
6050       else if (unformat (i, "disable"))
6051         enable = 0;
6052       else
6053         break;
6054     }
6055
6056   if (enable == -1)
6057     {
6058       errmsg ("missing enable|disable");
6059       return -99;
6060     }
6061
6062   M (WANT_INTERFACE_EVENTS, mp);
6063   mp->enable_disable = enable;
6064
6065   vam->interface_event_display = enable;
6066
6067   S (mp);
6068   W (ret);
6069   return ret;
6070 }
6071
6072
6073 /* Note: non-static, called once to set up the initial intfc table */
6074 int
6075 api_sw_interface_dump (vat_main_t * vam)
6076 {
6077   vl_api_sw_interface_dump_t *mp;
6078   vl_api_control_ping_t *mp_ping;
6079   hash_pair_t *p;
6080   name_sort_t *nses = 0, *ns;
6081   sw_interface_subif_t *sub = NULL;
6082   int ret;
6083
6084   /* Toss the old name table */
6085   /* *INDENT-OFF* */
6086   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6087   ({
6088     vec_add2 (nses, ns, 1);
6089     ns->name = (u8 *)(p->key);
6090     ns->value = (u32) p->value[0];
6091   }));
6092   /* *INDENT-ON* */
6093
6094   hash_free (vam->sw_if_index_by_interface_name);
6095
6096   vec_foreach (ns, nses) vec_free (ns->name);
6097
6098   vec_free (nses);
6099
6100   vec_foreach (sub, vam->sw_if_subif_table)
6101   {
6102     vec_free (sub->interface_name);
6103   }
6104   vec_free (vam->sw_if_subif_table);
6105
6106   /* recreate the interface name hash table */
6107   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6108
6109   /* Get list of ethernets */
6110   M (SW_INTERFACE_DUMP, mp);
6111   mp->name_filter_valid = 1;
6112   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6113   S (mp);
6114
6115   /* and local / loopback interfaces */
6116   M (SW_INTERFACE_DUMP, mp);
6117   mp->name_filter_valid = 1;
6118   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6119   S (mp);
6120
6121   /* and packet-generator interfaces */
6122   M (SW_INTERFACE_DUMP, mp);
6123   mp->name_filter_valid = 1;
6124   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6125   S (mp);
6126
6127   /* and vxlan-gpe tunnel interfaces */
6128   M (SW_INTERFACE_DUMP, mp);
6129   mp->name_filter_valid = 1;
6130   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6131            sizeof (mp->name_filter) - 1);
6132   S (mp);
6133
6134   /* and vxlan tunnel interfaces */
6135   M (SW_INTERFACE_DUMP, mp);
6136   mp->name_filter_valid = 1;
6137   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6138   S (mp);
6139
6140   /* and geneve tunnel interfaces */
6141   M (SW_INTERFACE_DUMP, mp);
6142   mp->name_filter_valid = 1;
6143   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6144   S (mp);
6145
6146   /* and host (af_packet) interfaces */
6147   M (SW_INTERFACE_DUMP, mp);
6148   mp->name_filter_valid = 1;
6149   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6150   S (mp);
6151
6152   /* and l2tpv3 tunnel interfaces */
6153   M (SW_INTERFACE_DUMP, mp);
6154   mp->name_filter_valid = 1;
6155   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6156            sizeof (mp->name_filter) - 1);
6157   S (mp);
6158
6159   /* and GRE tunnel interfaces */
6160   M (SW_INTERFACE_DUMP, mp);
6161   mp->name_filter_valid = 1;
6162   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6163   S (mp);
6164
6165   /* and LISP-GPE interfaces */
6166   M (SW_INTERFACE_DUMP, mp);
6167   mp->name_filter_valid = 1;
6168   strncpy ((char *) mp->name_filter, "lisp_gpe",
6169            sizeof (mp->name_filter) - 1);
6170   S (mp);
6171
6172   /* and IPSEC tunnel interfaces */
6173   M (SW_INTERFACE_DUMP, mp);
6174   mp->name_filter_valid = 1;
6175   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6176   S (mp);
6177
6178   /* Use a control ping for synchronization */
6179   MPING (CONTROL_PING, mp_ping);
6180   S (mp_ping);
6181
6182   W (ret);
6183   return ret;
6184 }
6185
6186 static int
6187 api_sw_interface_set_flags (vat_main_t * vam)
6188 {
6189   unformat_input_t *i = vam->input;
6190   vl_api_sw_interface_set_flags_t *mp;
6191   u32 sw_if_index;
6192   u8 sw_if_index_set = 0;
6193   u8 admin_up = 0;
6194   int ret;
6195
6196   /* Parse args required to build the message */
6197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6198     {
6199       if (unformat (i, "admin-up"))
6200         admin_up = 1;
6201       else if (unformat (i, "admin-down"))
6202         admin_up = 0;
6203       else
6204         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6205         sw_if_index_set = 1;
6206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6207         sw_if_index_set = 1;
6208       else
6209         break;
6210     }
6211
6212   if (sw_if_index_set == 0)
6213     {
6214       errmsg ("missing interface name or sw_if_index");
6215       return -99;
6216     }
6217
6218   /* Construct the API message */
6219   M (SW_INTERFACE_SET_FLAGS, mp);
6220   mp->sw_if_index = ntohl (sw_if_index);
6221   mp->admin_up_down = admin_up;
6222
6223   /* send it... */
6224   S (mp);
6225
6226   /* Wait for a reply, return the good/bad news... */
6227   W (ret);
6228   return ret;
6229 }
6230
6231 static int
6232 api_sw_interface_clear_stats (vat_main_t * vam)
6233 {
6234   unformat_input_t *i = vam->input;
6235   vl_api_sw_interface_clear_stats_t *mp;
6236   u32 sw_if_index;
6237   u8 sw_if_index_set = 0;
6238   int ret;
6239
6240   /* Parse args required to build the message */
6241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6242     {
6243       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6244         sw_if_index_set = 1;
6245       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6246         sw_if_index_set = 1;
6247       else
6248         break;
6249     }
6250
6251   /* Construct the API message */
6252   M (SW_INTERFACE_CLEAR_STATS, mp);
6253
6254   if (sw_if_index_set == 1)
6255     mp->sw_if_index = ntohl (sw_if_index);
6256   else
6257     mp->sw_if_index = ~0;
6258
6259   /* send it... */
6260   S (mp);
6261
6262   /* Wait for a reply, return the good/bad news... */
6263   W (ret);
6264   return ret;
6265 }
6266
6267 static int
6268 api_sw_interface_add_del_address (vat_main_t * vam)
6269 {
6270   unformat_input_t *i = vam->input;
6271   vl_api_sw_interface_add_del_address_t *mp;
6272   u32 sw_if_index;
6273   u8 sw_if_index_set = 0;
6274   u8 is_add = 1, del_all = 0;
6275   u32 address_length = 0;
6276   u8 v4_address_set = 0;
6277   u8 v6_address_set = 0;
6278   ip4_address_t v4address;
6279   ip6_address_t v6address;
6280   int ret;
6281
6282   /* Parse args required to build the message */
6283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6284     {
6285       if (unformat (i, "del-all"))
6286         del_all = 1;
6287       else if (unformat (i, "del"))
6288         is_add = 0;
6289       else
6290         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6291         sw_if_index_set = 1;
6292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6293         sw_if_index_set = 1;
6294       else if (unformat (i, "%U/%d",
6295                          unformat_ip4_address, &v4address, &address_length))
6296         v4_address_set = 1;
6297       else if (unformat (i, "%U/%d",
6298                          unformat_ip6_address, &v6address, &address_length))
6299         v6_address_set = 1;
6300       else
6301         break;
6302     }
6303
6304   if (sw_if_index_set == 0)
6305     {
6306       errmsg ("missing interface name or sw_if_index");
6307       return -99;
6308     }
6309   if (v4_address_set && v6_address_set)
6310     {
6311       errmsg ("both v4 and v6 addresses set");
6312       return -99;
6313     }
6314   if (!v4_address_set && !v6_address_set && !del_all)
6315     {
6316       errmsg ("no addresses set");
6317       return -99;
6318     }
6319
6320   /* Construct the API message */
6321   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6322
6323   mp->sw_if_index = ntohl (sw_if_index);
6324   mp->is_add = is_add;
6325   mp->del_all = del_all;
6326   if (v6_address_set)
6327     {
6328       mp->is_ipv6 = 1;
6329       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6330     }
6331   else
6332     {
6333       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6334     }
6335   mp->address_length = address_length;
6336
6337   /* send it... */
6338   S (mp);
6339
6340   /* Wait for a reply, return good/bad news  */
6341   W (ret);
6342   return ret;
6343 }
6344
6345 static int
6346 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_sw_interface_set_mpls_enable_t *mp;
6350   u32 sw_if_index;
6351   u8 sw_if_index_set = 0;
6352   u8 enable = 1;
6353   int ret;
6354
6355   /* Parse args required to build the message */
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "disable"))
6363         enable = 0;
6364       else if (unformat (i, "dis"))
6365         enable = 0;
6366       else
6367         break;
6368     }
6369
6370   if (sw_if_index_set == 0)
6371     {
6372       errmsg ("missing interface name or sw_if_index");
6373       return -99;
6374     }
6375
6376   /* Construct the API message */
6377   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6378
6379   mp->sw_if_index = ntohl (sw_if_index);
6380   mp->enable = enable;
6381
6382   /* send it... */
6383   S (mp);
6384
6385   /* Wait for a reply... */
6386   W (ret);
6387   return ret;
6388 }
6389
6390 static int
6391 api_sw_interface_set_table (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_set_table_t *mp;
6395   u32 sw_if_index, vrf_id = 0;
6396   u8 sw_if_index_set = 0;
6397   u8 is_ipv6 = 0;
6398   int ret;
6399
6400   /* Parse args required to build the message */
6401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402     {
6403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6404         sw_if_index_set = 1;
6405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "vrf %d", &vrf_id))
6408         ;
6409       else if (unformat (i, "ipv6"))
6410         is_ipv6 = 1;
6411       else
6412         break;
6413     }
6414
6415   if (sw_if_index_set == 0)
6416     {
6417       errmsg ("missing interface name or sw_if_index");
6418       return -99;
6419     }
6420
6421   /* Construct the API message */
6422   M (SW_INTERFACE_SET_TABLE, mp);
6423
6424   mp->sw_if_index = ntohl (sw_if_index);
6425   mp->is_ipv6 = is_ipv6;
6426   mp->vrf_id = ntohl (vrf_id);
6427
6428   /* send it... */
6429   S (mp);
6430
6431   /* Wait for a reply... */
6432   W (ret);
6433   return ret;
6434 }
6435
6436 static void vl_api_sw_interface_get_table_reply_t_handler
6437   (vl_api_sw_interface_get_table_reply_t * mp)
6438 {
6439   vat_main_t *vam = &vat_main;
6440
6441   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6442
6443   vam->retval = ntohl (mp->retval);
6444   vam->result_ready = 1;
6445
6446 }
6447
6448 static void vl_api_sw_interface_get_table_reply_t_handler_json
6449   (vl_api_sw_interface_get_table_reply_t * mp)
6450 {
6451   vat_main_t *vam = &vat_main;
6452   vat_json_node_t node;
6453
6454   vat_json_init_object (&node);
6455   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6456   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6457
6458   vat_json_print (vam->ofp, &node);
6459   vat_json_free (&node);
6460
6461   vam->retval = ntohl (mp->retval);
6462   vam->result_ready = 1;
6463 }
6464
6465 static int
6466 api_sw_interface_get_table (vat_main_t * vam)
6467 {
6468   unformat_input_t *i = vam->input;
6469   vl_api_sw_interface_get_table_t *mp;
6470   u32 sw_if_index;
6471   u8 sw_if_index_set = 0;
6472   u8 is_ipv6 = 0;
6473   int ret;
6474
6475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6476     {
6477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6478         sw_if_index_set = 1;
6479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6480         sw_if_index_set = 1;
6481       else if (unformat (i, "ipv6"))
6482         is_ipv6 = 1;
6483       else
6484         break;
6485     }
6486
6487   if (sw_if_index_set == 0)
6488     {
6489       errmsg ("missing interface name or sw_if_index");
6490       return -99;
6491     }
6492
6493   M (SW_INTERFACE_GET_TABLE, mp);
6494   mp->sw_if_index = htonl (sw_if_index);
6495   mp->is_ipv6 = is_ipv6;
6496
6497   S (mp);
6498   W (ret);
6499   return ret;
6500 }
6501
6502 static int
6503 api_sw_interface_set_vpath (vat_main_t * vam)
6504 {
6505   unformat_input_t *i = vam->input;
6506   vl_api_sw_interface_set_vpath_t *mp;
6507   u32 sw_if_index = 0;
6508   u8 sw_if_index_set = 0;
6509   u8 is_enable = 0;
6510   int ret;
6511
6512   /* Parse args required to build the message */
6513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6514     {
6515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "enable"))
6520         is_enable = 1;
6521       else if (unformat (i, "disable"))
6522         is_enable = 0;
6523       else
6524         break;
6525     }
6526
6527   if (sw_if_index_set == 0)
6528     {
6529       errmsg ("missing interface name or sw_if_index");
6530       return -99;
6531     }
6532
6533   /* Construct the API message */
6534   M (SW_INTERFACE_SET_VPATH, mp);
6535
6536   mp->sw_if_index = ntohl (sw_if_index);
6537   mp->enable = is_enable;
6538
6539   /* send it... */
6540   S (mp);
6541
6542   /* Wait for a reply... */
6543   W (ret);
6544   return ret;
6545 }
6546
6547 static int
6548 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6549 {
6550   unformat_input_t *i = vam->input;
6551   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6552   u32 sw_if_index = 0;
6553   u8 sw_if_index_set = 0;
6554   u8 is_enable = 1;
6555   u8 is_ipv6 = 0;
6556   int ret;
6557
6558   /* Parse args required to build the message */
6559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6560     {
6561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6562         sw_if_index_set = 1;
6563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6564         sw_if_index_set = 1;
6565       else if (unformat (i, "enable"))
6566         is_enable = 1;
6567       else if (unformat (i, "disable"))
6568         is_enable = 0;
6569       else if (unformat (i, "ip4"))
6570         is_ipv6 = 0;
6571       else if (unformat (i, "ip6"))
6572         is_ipv6 = 1;
6573       else
6574         break;
6575     }
6576
6577   if (sw_if_index_set == 0)
6578     {
6579       errmsg ("missing interface name or sw_if_index");
6580       return -99;
6581     }
6582
6583   /* Construct the API message */
6584   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6585
6586   mp->sw_if_index = ntohl (sw_if_index);
6587   mp->enable = is_enable;
6588   mp->is_ipv6 = is_ipv6;
6589
6590   /* send it... */
6591   S (mp);
6592
6593   /* Wait for a reply... */
6594   W (ret);
6595   return ret;
6596 }
6597
6598 static int
6599 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6600 {
6601   unformat_input_t *i = vam->input;
6602   vl_api_sw_interface_set_geneve_bypass_t *mp;
6603   u32 sw_if_index = 0;
6604   u8 sw_if_index_set = 0;
6605   u8 is_enable = 1;
6606   u8 is_ipv6 = 0;
6607   int ret;
6608
6609   /* Parse args required to build the message */
6610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6611     {
6612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6613         sw_if_index_set = 1;
6614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6615         sw_if_index_set = 1;
6616       else if (unformat (i, "enable"))
6617         is_enable = 1;
6618       else if (unformat (i, "disable"))
6619         is_enable = 0;
6620       else if (unformat (i, "ip4"))
6621         is_ipv6 = 0;
6622       else if (unformat (i, "ip6"))
6623         is_ipv6 = 1;
6624       else
6625         break;
6626     }
6627
6628   if (sw_if_index_set == 0)
6629     {
6630       errmsg ("missing interface name or sw_if_index");
6631       return -99;
6632     }
6633
6634   /* Construct the API message */
6635   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6636
6637   mp->sw_if_index = ntohl (sw_if_index);
6638   mp->enable = is_enable;
6639   mp->is_ipv6 = is_ipv6;
6640
6641   /* send it... */
6642   S (mp);
6643
6644   /* Wait for a reply... */
6645   W (ret);
6646   return ret;
6647 }
6648
6649 static int
6650 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6651 {
6652   unformat_input_t *i = vam->input;
6653   vl_api_sw_interface_set_l2_xconnect_t *mp;
6654   u32 rx_sw_if_index;
6655   u8 rx_sw_if_index_set = 0;
6656   u32 tx_sw_if_index;
6657   u8 tx_sw_if_index_set = 0;
6658   u8 enable = 1;
6659   int ret;
6660
6661   /* Parse args required to build the message */
6662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663     {
6664       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6665         rx_sw_if_index_set = 1;
6666       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6667         tx_sw_if_index_set = 1;
6668       else if (unformat (i, "rx"))
6669         {
6670           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671             {
6672               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6673                             &rx_sw_if_index))
6674                 rx_sw_if_index_set = 1;
6675             }
6676           else
6677             break;
6678         }
6679       else if (unformat (i, "tx"))
6680         {
6681           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6682             {
6683               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6684                             &tx_sw_if_index))
6685                 tx_sw_if_index_set = 1;
6686             }
6687           else
6688             break;
6689         }
6690       else if (unformat (i, "enable"))
6691         enable = 1;
6692       else if (unformat (i, "disable"))
6693         enable = 0;
6694       else
6695         break;
6696     }
6697
6698   if (rx_sw_if_index_set == 0)
6699     {
6700       errmsg ("missing rx interface name or rx_sw_if_index");
6701       return -99;
6702     }
6703
6704   if (enable && (tx_sw_if_index_set == 0))
6705     {
6706       errmsg ("missing tx interface name or tx_sw_if_index");
6707       return -99;
6708     }
6709
6710   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6711
6712   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6713   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6714   mp->enable = enable;
6715
6716   S (mp);
6717   W (ret);
6718   return ret;
6719 }
6720
6721 static int
6722 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6723 {
6724   unformat_input_t *i = vam->input;
6725   vl_api_sw_interface_set_l2_bridge_t *mp;
6726   u32 rx_sw_if_index;
6727   u8 rx_sw_if_index_set = 0;
6728   u32 bd_id;
6729   u8 bd_id_set = 0;
6730   u8 bvi = 0;
6731   u32 shg = 0;
6732   u8 enable = 1;
6733   int ret;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6739         rx_sw_if_index_set = 1;
6740       else if (unformat (i, "bd_id %d", &bd_id))
6741         bd_id_set = 1;
6742       else
6743         if (unformat
6744             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6745         rx_sw_if_index_set = 1;
6746       else if (unformat (i, "shg %d", &shg))
6747         ;
6748       else if (unformat (i, "bvi"))
6749         bvi = 1;
6750       else if (unformat (i, "enable"))
6751         enable = 1;
6752       else if (unformat (i, "disable"))
6753         enable = 0;
6754       else
6755         break;
6756     }
6757
6758   if (rx_sw_if_index_set == 0)
6759     {
6760       errmsg ("missing rx interface name or sw_if_index");
6761       return -99;
6762     }
6763
6764   if (enable && (bd_id_set == 0))
6765     {
6766       errmsg ("missing bridge domain");
6767       return -99;
6768     }
6769
6770   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6771
6772   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6773   mp->bd_id = ntohl (bd_id);
6774   mp->shg = (u8) shg;
6775   mp->bvi = bvi;
6776   mp->enable = enable;
6777
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_bridge_domain_dump (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_bridge_domain_dump_t *mp;
6788   vl_api_control_ping_t *mp_ping;
6789   u32 bd_id = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "bd_id %d", &bd_id))
6796         ;
6797       else
6798         break;
6799     }
6800
6801   M (BRIDGE_DOMAIN_DUMP, mp);
6802   mp->bd_id = ntohl (bd_id);
6803   S (mp);
6804
6805   /* Use a control ping for synchronization */
6806   MPING (CONTROL_PING, mp_ping);
6807   S (mp_ping);
6808
6809   W (ret);
6810   return ret;
6811 }
6812
6813 static int
6814 api_bridge_domain_add_del (vat_main_t * vam)
6815 {
6816   unformat_input_t *i = vam->input;
6817   vl_api_bridge_domain_add_del_t *mp;
6818   u32 bd_id = ~0;
6819   u8 is_add = 1;
6820   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6821   u8 *bd_tag = NULL;
6822   u32 mac_age = 0;
6823   int ret;
6824
6825   /* Parse args required to build the message */
6826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6827     {
6828       if (unformat (i, "bd_id %d", &bd_id))
6829         ;
6830       else if (unformat (i, "flood %d", &flood))
6831         ;
6832       else if (unformat (i, "uu-flood %d", &uu_flood))
6833         ;
6834       else if (unformat (i, "forward %d", &forward))
6835         ;
6836       else if (unformat (i, "learn %d", &learn))
6837         ;
6838       else if (unformat (i, "arp-term %d", &arp_term))
6839         ;
6840       else if (unformat (i, "mac-age %d", &mac_age))
6841         ;
6842       else if (unformat (i, "bd-tag %s", &bd_tag))
6843         ;
6844       else if (unformat (i, "del"))
6845         {
6846           is_add = 0;
6847           flood = uu_flood = forward = learn = 0;
6848         }
6849       else
6850         break;
6851     }
6852
6853   if (bd_id == ~0)
6854     {
6855       errmsg ("missing bridge domain");
6856       ret = -99;
6857       goto done;
6858     }
6859
6860   if (mac_age > 255)
6861     {
6862       errmsg ("mac age must be less than 256 ");
6863       ret = -99;
6864       goto done;
6865     }
6866
6867   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6868     {
6869       errmsg ("bd-tag cannot be longer than 63");
6870       ret = -99;
6871       goto done;
6872     }
6873
6874   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6875
6876   mp->bd_id = ntohl (bd_id);
6877   mp->flood = flood;
6878   mp->uu_flood = uu_flood;
6879   mp->forward = forward;
6880   mp->learn = learn;
6881   mp->arp_term = arp_term;
6882   mp->is_add = is_add;
6883   mp->mac_age = (u8) mac_age;
6884   if (bd_tag)
6885     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6886
6887   S (mp);
6888   W (ret);
6889
6890 done:
6891   vec_free (bd_tag);
6892   return ret;
6893 }
6894
6895 static int
6896 api_l2fib_flush_bd (vat_main_t * vam)
6897 {
6898   unformat_input_t *i = vam->input;
6899   vl_api_l2fib_flush_bd_t *mp;
6900   u32 bd_id = ~0;
6901   int ret;
6902
6903   /* Parse args required to build the message */
6904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905     {
6906       if (unformat (i, "bd_id %d", &bd_id));
6907       else
6908         break;
6909     }
6910
6911   if (bd_id == ~0)
6912     {
6913       errmsg ("missing bridge domain");
6914       return -99;
6915     }
6916
6917   M (L2FIB_FLUSH_BD, mp);
6918
6919   mp->bd_id = htonl (bd_id);
6920
6921   S (mp);
6922   W (ret);
6923   return ret;
6924 }
6925
6926 static int
6927 api_l2fib_flush_int (vat_main_t * vam)
6928 {
6929   unformat_input_t *i = vam->input;
6930   vl_api_l2fib_flush_int_t *mp;
6931   u32 sw_if_index = ~0;
6932   int ret;
6933
6934   /* Parse args required to build the message */
6935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6936     {
6937       if (unformat (i, "sw_if_index %d", &sw_if_index));
6938       else
6939         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6940       else
6941         break;
6942     }
6943
6944   if (sw_if_index == ~0)
6945     {
6946       errmsg ("missing interface name or sw_if_index");
6947       return -99;
6948     }
6949
6950   M (L2FIB_FLUSH_INT, mp);
6951
6952   mp->sw_if_index = ntohl (sw_if_index);
6953
6954   S (mp);
6955   W (ret);
6956   return ret;
6957 }
6958
6959 static int
6960 api_l2fib_add_del (vat_main_t * vam)
6961 {
6962   unformat_input_t *i = vam->input;
6963   vl_api_l2fib_add_del_t *mp;
6964   f64 timeout;
6965   u64 mac = 0;
6966   u8 mac_set = 0;
6967   u32 bd_id;
6968   u8 bd_id_set = 0;
6969   u32 sw_if_index = ~0;
6970   u8 sw_if_index_set = 0;
6971   u8 is_add = 1;
6972   u8 static_mac = 0;
6973   u8 filter_mac = 0;
6974   u8 bvi_mac = 0;
6975   int count = 1;
6976   f64 before = 0;
6977   int j;
6978
6979   /* Parse args required to build the message */
6980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6981     {
6982       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6983         mac_set = 1;
6984       else if (unformat (i, "bd_id %d", &bd_id))
6985         bd_id_set = 1;
6986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6987         sw_if_index_set = 1;
6988       else if (unformat (i, "sw_if"))
6989         {
6990           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6991             {
6992               if (unformat
6993                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6994                 sw_if_index_set = 1;
6995             }
6996           else
6997             break;
6998         }
6999       else if (unformat (i, "static"))
7000         static_mac = 1;
7001       else if (unformat (i, "filter"))
7002         {
7003           filter_mac = 1;
7004           static_mac = 1;
7005         }
7006       else if (unformat (i, "bvi"))
7007         {
7008           bvi_mac = 1;
7009           static_mac = 1;
7010         }
7011       else if (unformat (i, "del"))
7012         is_add = 0;
7013       else if (unformat (i, "count %d", &count))
7014         ;
7015       else
7016         break;
7017     }
7018
7019   if (mac_set == 0)
7020     {
7021       errmsg ("missing mac address");
7022       return -99;
7023     }
7024
7025   if (bd_id_set == 0)
7026     {
7027       errmsg ("missing bridge domain");
7028       return -99;
7029     }
7030
7031   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7032     {
7033       errmsg ("missing interface name or sw_if_index");
7034       return -99;
7035     }
7036
7037   if (count > 1)
7038     {
7039       /* Turn on async mode */
7040       vam->async_mode = 1;
7041       vam->async_errors = 0;
7042       before = vat_time_now (vam);
7043     }
7044
7045   for (j = 0; j < count; j++)
7046     {
7047       M (L2FIB_ADD_DEL, mp);
7048
7049       mp->mac = mac;
7050       mp->bd_id = ntohl (bd_id);
7051       mp->is_add = is_add;
7052
7053       if (is_add)
7054         {
7055           mp->sw_if_index = ntohl (sw_if_index);
7056           mp->static_mac = static_mac;
7057           mp->filter_mac = filter_mac;
7058           mp->bvi_mac = bvi_mac;
7059         }
7060       increment_mac_address (&mac);
7061       /* send it... */
7062       S (mp);
7063     }
7064
7065   if (count > 1)
7066     {
7067       vl_api_control_ping_t *mp_ping;
7068       f64 after;
7069
7070       /* Shut off async mode */
7071       vam->async_mode = 0;
7072
7073       MPING (CONTROL_PING, mp_ping);
7074       S (mp_ping);
7075
7076       timeout = vat_time_now (vam) + 1.0;
7077       while (vat_time_now (vam) < timeout)
7078         if (vam->result_ready == 1)
7079           goto out;
7080       vam->retval = -99;
7081
7082     out:
7083       if (vam->retval == -99)
7084         errmsg ("timeout");
7085
7086       if (vam->async_errors > 0)
7087         {
7088           errmsg ("%d asynchronous errors", vam->async_errors);
7089           vam->retval = -98;
7090         }
7091       vam->async_errors = 0;
7092       after = vat_time_now (vam);
7093
7094       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7095              count, after - before, count / (after - before));
7096     }
7097   else
7098     {
7099       int ret;
7100
7101       /* Wait for a reply... */
7102       W (ret);
7103       return ret;
7104     }
7105   /* Return the good/bad news */
7106   return (vam->retval);
7107 }
7108
7109 static int
7110 api_bridge_domain_set_mac_age (vat_main_t * vam)
7111 {
7112   unformat_input_t *i = vam->input;
7113   vl_api_bridge_domain_set_mac_age_t *mp;
7114   u32 bd_id = ~0;
7115   u32 mac_age = 0;
7116   int ret;
7117
7118   /* Parse args required to build the message */
7119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7120     {
7121       if (unformat (i, "bd_id %d", &bd_id));
7122       else if (unformat (i, "mac-age %d", &mac_age));
7123       else
7124         break;
7125     }
7126
7127   if (bd_id == ~0)
7128     {
7129       errmsg ("missing bridge domain");
7130       return -99;
7131     }
7132
7133   if (mac_age > 255)
7134     {
7135       errmsg ("mac age must be less than 256 ");
7136       return -99;
7137     }
7138
7139   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7140
7141   mp->bd_id = htonl (bd_id);
7142   mp->mac_age = (u8) mac_age;
7143
7144   S (mp);
7145   W (ret);
7146   return ret;
7147 }
7148
7149 static int
7150 api_l2_flags (vat_main_t * vam)
7151 {
7152   unformat_input_t *i = vam->input;
7153   vl_api_l2_flags_t *mp;
7154   u32 sw_if_index;
7155   u32 flags = 0;
7156   u8 sw_if_index_set = 0;
7157   u8 is_set = 0;
7158   int ret;
7159
7160   /* Parse args required to build the message */
7161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7162     {
7163       if (unformat (i, "sw_if_index %d", &sw_if_index))
7164         sw_if_index_set = 1;
7165       else if (unformat (i, "sw_if"))
7166         {
7167           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7168             {
7169               if (unformat
7170                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7171                 sw_if_index_set = 1;
7172             }
7173           else
7174             break;
7175         }
7176       else if (unformat (i, "learn"))
7177         flags |= L2_LEARN;
7178       else if (unformat (i, "forward"))
7179         flags |= L2_FWD;
7180       else if (unformat (i, "flood"))
7181         flags |= L2_FLOOD;
7182       else if (unformat (i, "uu-flood"))
7183         flags |= L2_UU_FLOOD;
7184       else if (unformat (i, "arp-term"))
7185         flags |= L2_ARP_TERM;
7186       else if (unformat (i, "off"))
7187         is_set = 0;
7188       else if (unformat (i, "disable"))
7189         is_set = 0;
7190       else
7191         break;
7192     }
7193
7194   if (sw_if_index_set == 0)
7195     {
7196       errmsg ("missing interface name or sw_if_index");
7197       return -99;
7198     }
7199
7200   M (L2_FLAGS, mp);
7201
7202   mp->sw_if_index = ntohl (sw_if_index);
7203   mp->feature_bitmap = ntohl (flags);
7204   mp->is_set = is_set;
7205
7206   S (mp);
7207   W (ret);
7208   return ret;
7209 }
7210
7211 static int
7212 api_bridge_flags (vat_main_t * vam)
7213 {
7214   unformat_input_t *i = vam->input;
7215   vl_api_bridge_flags_t *mp;
7216   u32 bd_id;
7217   u8 bd_id_set = 0;
7218   u8 is_set = 1;
7219   u32 flags = 0;
7220   int ret;
7221
7222   /* Parse args required to build the message */
7223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224     {
7225       if (unformat (i, "bd_id %d", &bd_id))
7226         bd_id_set = 1;
7227       else if (unformat (i, "learn"))
7228         flags |= L2_LEARN;
7229       else if (unformat (i, "forward"))
7230         flags |= L2_FWD;
7231       else if (unformat (i, "flood"))
7232         flags |= L2_FLOOD;
7233       else if (unformat (i, "uu-flood"))
7234         flags |= L2_UU_FLOOD;
7235       else if (unformat (i, "arp-term"))
7236         flags |= L2_ARP_TERM;
7237       else if (unformat (i, "off"))
7238         is_set = 0;
7239       else if (unformat (i, "disable"))
7240         is_set = 0;
7241       else
7242         break;
7243     }
7244
7245   if (bd_id_set == 0)
7246     {
7247       errmsg ("missing bridge domain");
7248       return -99;
7249     }
7250
7251   M (BRIDGE_FLAGS, mp);
7252
7253   mp->bd_id = ntohl (bd_id);
7254   mp->feature_bitmap = ntohl (flags);
7255   mp->is_set = is_set;
7256
7257   S (mp);
7258   W (ret);
7259   return ret;
7260 }
7261
7262 static int
7263 api_bd_ip_mac_add_del (vat_main_t * vam)
7264 {
7265   unformat_input_t *i = vam->input;
7266   vl_api_bd_ip_mac_add_del_t *mp;
7267   u32 bd_id;
7268   u8 is_ipv6 = 0;
7269   u8 is_add = 1;
7270   u8 bd_id_set = 0;
7271   u8 ip_set = 0;
7272   u8 mac_set = 0;
7273   ip4_address_t v4addr;
7274   ip6_address_t v6addr;
7275   u8 macaddr[6];
7276   int ret;
7277
7278
7279   /* Parse args required to build the message */
7280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7281     {
7282       if (unformat (i, "bd_id %d", &bd_id))
7283         {
7284           bd_id_set++;
7285         }
7286       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7287         {
7288           ip_set++;
7289         }
7290       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7291         {
7292           ip_set++;
7293           is_ipv6++;
7294         }
7295       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7296         {
7297           mac_set++;
7298         }
7299       else if (unformat (i, "del"))
7300         is_add = 0;
7301       else
7302         break;
7303     }
7304
7305   if (bd_id_set == 0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310   else if (ip_set == 0)
7311     {
7312       errmsg ("missing IP address");
7313       return -99;
7314     }
7315   else if (mac_set == 0)
7316     {
7317       errmsg ("missing MAC address");
7318       return -99;
7319     }
7320
7321   M (BD_IP_MAC_ADD_DEL, mp);
7322
7323   mp->bd_id = ntohl (bd_id);
7324   mp->is_ipv6 = is_ipv6;
7325   mp->is_add = is_add;
7326   if (is_ipv6)
7327     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7328   else
7329     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7330   clib_memcpy (mp->mac_address, macaddr, 6);
7331   S (mp);
7332   W (ret);
7333   return ret;
7334 }
7335
7336 static int
7337 api_tap_connect (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_tap_connect_t *mp;
7341   u8 mac_address[6];
7342   u8 random_mac = 1;
7343   u8 name_set = 0;
7344   u8 *tap_name;
7345   u8 *tag = 0;
7346   ip4_address_t ip4_address;
7347   u32 ip4_mask_width;
7348   int ip4_address_set = 0;
7349   ip6_address_t ip6_address;
7350   u32 ip6_mask_width;
7351   int ip6_address_set = 0;
7352   int ret;
7353
7354   memset (mac_address, 0, sizeof (mac_address));
7355
7356   /* Parse args required to build the message */
7357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7358     {
7359       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7360         {
7361           random_mac = 0;
7362         }
7363       else if (unformat (i, "random-mac"))
7364         random_mac = 1;
7365       else if (unformat (i, "tapname %s", &tap_name))
7366         name_set = 1;
7367       else if (unformat (i, "tag %s", &tag))
7368         ;
7369       else if (unformat (i, "address %U/%d",
7370                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7371         ip4_address_set = 1;
7372       else if (unformat (i, "address %U/%d",
7373                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7374         ip6_address_set = 1;
7375       else
7376         break;
7377     }
7378
7379   if (name_set == 0)
7380     {
7381       errmsg ("missing tap name");
7382       return -99;
7383     }
7384   if (vec_len (tap_name) > 63)
7385     {
7386       errmsg ("tap name too long");
7387       return -99;
7388     }
7389   vec_add1 (tap_name, 0);
7390
7391   if (vec_len (tag) > 63)
7392     {
7393       errmsg ("tag too long");
7394       return -99;
7395     }
7396
7397   /* Construct the API message */
7398   M (TAP_CONNECT, mp);
7399
7400   mp->use_random_mac = random_mac;
7401   clib_memcpy (mp->mac_address, mac_address, 6);
7402   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7403   if (tag)
7404     clib_memcpy (mp->tag, tag, vec_len (tag));
7405
7406   if (ip4_address_set)
7407     {
7408       mp->ip4_address_set = 1;
7409       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7410       mp->ip4_mask_width = ip4_mask_width;
7411     }
7412   if (ip6_address_set)
7413     {
7414       mp->ip6_address_set = 1;
7415       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7416       mp->ip6_mask_width = ip6_mask_width;
7417     }
7418
7419   vec_free (tap_name);
7420   vec_free (tag);
7421
7422   /* send it... */
7423   S (mp);
7424
7425   /* Wait for a reply... */
7426   W (ret);
7427   return ret;
7428 }
7429
7430 static int
7431 api_tap_modify (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_tap_modify_t *mp;
7435   u8 mac_address[6];
7436   u8 random_mac = 1;
7437   u8 name_set = 0;
7438   u8 *tap_name;
7439   u32 sw_if_index = ~0;
7440   u8 sw_if_index_set = 0;
7441   int ret;
7442
7443   memset (mac_address, 0, sizeof (mac_address));
7444
7445   /* Parse args required to build the message */
7446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7447     {
7448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7449         sw_if_index_set = 1;
7450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7451         sw_if_index_set = 1;
7452       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7453         {
7454           random_mac = 0;
7455         }
7456       else if (unformat (i, "random-mac"))
7457         random_mac = 1;
7458       else if (unformat (i, "tapname %s", &tap_name))
7459         name_set = 1;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing vpp interface name");
7467       return -99;
7468     }
7469   if (name_set == 0)
7470     {
7471       errmsg ("missing tap name");
7472       return -99;
7473     }
7474   if (vec_len (tap_name) > 63)
7475     {
7476       errmsg ("tap name too long");
7477     }
7478   vec_add1 (tap_name, 0);
7479
7480   /* Construct the API message */
7481   M (TAP_MODIFY, mp);
7482
7483   mp->use_random_mac = random_mac;
7484   mp->sw_if_index = ntohl (sw_if_index);
7485   clib_memcpy (mp->mac_address, mac_address, 6);
7486   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7487   vec_free (tap_name);
7488
7489   /* send it... */
7490   S (mp);
7491
7492   /* Wait for a reply... */
7493   W (ret);
7494   return ret;
7495 }
7496
7497 static int
7498 api_tap_delete (vat_main_t * vam)
7499 {
7500   unformat_input_t *i = vam->input;
7501   vl_api_tap_delete_t *mp;
7502   u32 sw_if_index = ~0;
7503   u8 sw_if_index_set = 0;
7504   int ret;
7505
7506   /* Parse args required to build the message */
7507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7508     {
7509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7510         sw_if_index_set = 1;
7511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7512         sw_if_index_set = 1;
7513       else
7514         break;
7515     }
7516
7517   if (sw_if_index_set == 0)
7518     {
7519       errmsg ("missing vpp interface name");
7520       return -99;
7521     }
7522
7523   /* Construct the API message */
7524   M (TAP_DELETE, mp);
7525
7526   mp->sw_if_index = ntohl (sw_if_index);
7527
7528   /* send it... */
7529   S (mp);
7530
7531   /* Wait for a reply... */
7532   W (ret);
7533   return ret;
7534 }
7535
7536 static int
7537 api_ip_table_add_del (vat_main_t * vam)
7538 {
7539   unformat_input_t *i = vam->input;
7540   vl_api_ip_table_add_del_t *mp;
7541   u32 table_id = ~0;
7542   u8 is_ipv6 = 0;
7543   u8 is_add = 1;
7544   int ret = 0;
7545
7546   /* Parse args required to build the message */
7547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7548     {
7549       if (unformat (i, "ipv6"))
7550         is_ipv6 = 1;
7551       else if (unformat (i, "del"))
7552         is_add = 0;
7553       else if (unformat (i, "add"))
7554         is_add = 1;
7555       else if (unformat (i, "table %d", &table_id))
7556         ;
7557       else
7558         {
7559           clib_warning ("parse error '%U'", format_unformat_error, i);
7560           return -99;
7561         }
7562     }
7563
7564   if (~0 == table_id)
7565     {
7566       errmsg ("missing table-ID");
7567       return -99;
7568     }
7569
7570   /* Construct the API message */
7571   M (IP_TABLE_ADD_DEL, mp);
7572
7573   mp->table_id = ntohl (table_id);
7574   mp->is_ipv6 = is_ipv6;
7575   mp->is_add = is_add;
7576
7577   /* send it... */
7578   S (mp);
7579
7580   /* Wait for a reply... */
7581   W (ret);
7582
7583   return ret;
7584 }
7585
7586 static int
7587 api_ip_add_del_route (vat_main_t * vam)
7588 {
7589   unformat_input_t *i = vam->input;
7590   vl_api_ip_add_del_route_t *mp;
7591   u32 sw_if_index = ~0, vrf_id = 0;
7592   u8 is_ipv6 = 0;
7593   u8 is_local = 0, is_drop = 0;
7594   u8 is_unreach = 0, is_prohibit = 0;
7595   u8 create_vrf_if_needed = 0;
7596   u8 is_add = 1;
7597   u32 next_hop_weight = 1;
7598   u8 is_multipath = 0;
7599   u8 address_set = 0;
7600   u8 address_length_set = 0;
7601   u32 next_hop_table_id = 0;
7602   u32 resolve_attempts = 0;
7603   u32 dst_address_length = 0;
7604   u8 next_hop_set = 0;
7605   ip4_address_t v4_dst_address, v4_next_hop_address;
7606   ip6_address_t v6_dst_address, v6_next_hop_address;
7607   int count = 1;
7608   int j;
7609   f64 before = 0;
7610   u32 random_add_del = 0;
7611   u32 *random_vector = 0;
7612   uword *random_hash;
7613   u32 random_seed = 0xdeaddabe;
7614   u32 classify_table_index = ~0;
7615   u8 is_classify = 0;
7616   u8 resolve_host = 0, resolve_attached = 0;
7617   mpls_label_t *next_hop_out_label_stack = NULL;
7618   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7619   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7625         ;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         ;
7628       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7629         {
7630           address_set = 1;
7631           is_ipv6 = 0;
7632         }
7633       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7634         {
7635           address_set = 1;
7636           is_ipv6 = 1;
7637         }
7638       else if (unformat (i, "/%d", &dst_address_length))
7639         {
7640           address_length_set = 1;
7641         }
7642
7643       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7644                                          &v4_next_hop_address))
7645         {
7646           next_hop_set = 1;
7647         }
7648       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7649                                          &v6_next_hop_address))
7650         {
7651           next_hop_set = 1;
7652         }
7653       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7654         ;
7655       else if (unformat (i, "weight %d", &next_hop_weight))
7656         ;
7657       else if (unformat (i, "drop"))
7658         {
7659           is_drop = 1;
7660         }
7661       else if (unformat (i, "null-send-unreach"))
7662         {
7663           is_unreach = 1;
7664         }
7665       else if (unformat (i, "null-send-prohibit"))
7666         {
7667           is_prohibit = 1;
7668         }
7669       else if (unformat (i, "local"))
7670         {
7671           is_local = 1;
7672         }
7673       else if (unformat (i, "classify %d", &classify_table_index))
7674         {
7675           is_classify = 1;
7676         }
7677       else if (unformat (i, "del"))
7678         is_add = 0;
7679       else if (unformat (i, "add"))
7680         is_add = 1;
7681       else if (unformat (i, "resolve-via-host"))
7682         resolve_host = 1;
7683       else if (unformat (i, "resolve-via-attached"))
7684         resolve_attached = 1;
7685       else if (unformat (i, "multipath"))
7686         is_multipath = 1;
7687       else if (unformat (i, "vrf %d", &vrf_id))
7688         ;
7689       else if (unformat (i, "create-vrf"))
7690         create_vrf_if_needed = 1;
7691       else if (unformat (i, "count %d", &count))
7692         ;
7693       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7694         ;
7695       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7696         ;
7697       else if (unformat (i, "out-label %d", &next_hop_out_label))
7698         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7699       else if (unformat (i, "via-label %d", &next_hop_via_label))
7700         ;
7701       else if (unformat (i, "random"))
7702         random_add_del = 1;
7703       else if (unformat (i, "seed %d", &random_seed))
7704         ;
7705       else
7706         {
7707           clib_warning ("parse error '%U'", format_unformat_error, i);
7708           return -99;
7709         }
7710     }
7711
7712   if (!next_hop_set && !is_drop && !is_local &&
7713       !is_classify && !is_unreach && !is_prohibit &&
7714       MPLS_LABEL_INVALID == next_hop_via_label)
7715     {
7716       errmsg
7717         ("next hop / local / drop / unreach / prohibit / classify not set");
7718       return -99;
7719     }
7720
7721   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7722     {
7723       errmsg ("next hop and next-hop via label set");
7724       return -99;
7725     }
7726   if (address_set == 0)
7727     {
7728       errmsg ("missing addresses");
7729       return -99;
7730     }
7731
7732   if (address_length_set == 0)
7733     {
7734       errmsg ("missing address length");
7735       return -99;
7736     }
7737
7738   /* Generate a pile of unique, random routes */
7739   if (random_add_del)
7740     {
7741       u32 this_random_address;
7742       random_hash = hash_create (count, sizeof (uword));
7743
7744       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7745       for (j = 0; j <= count; j++)
7746         {
7747           do
7748             {
7749               this_random_address = random_u32 (&random_seed);
7750               this_random_address =
7751                 clib_host_to_net_u32 (this_random_address);
7752             }
7753           while (hash_get (random_hash, this_random_address));
7754           vec_add1 (random_vector, this_random_address);
7755           hash_set (random_hash, this_random_address, 1);
7756         }
7757       hash_free (random_hash);
7758       v4_dst_address.as_u32 = random_vector[0];
7759     }
7760
7761   if (count > 1)
7762     {
7763       /* Turn on async mode */
7764       vam->async_mode = 1;
7765       vam->async_errors = 0;
7766       before = vat_time_now (vam);
7767     }
7768
7769   for (j = 0; j < count; j++)
7770     {
7771       /* Construct the API message */
7772       M2 (IP_ADD_DEL_ROUTE, mp,
7773           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7774
7775       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7776       mp->table_id = ntohl (vrf_id);
7777       mp->create_vrf_if_needed = create_vrf_if_needed;
7778
7779       mp->is_add = is_add;
7780       mp->is_drop = is_drop;
7781       mp->is_unreach = is_unreach;
7782       mp->is_prohibit = is_prohibit;
7783       mp->is_ipv6 = is_ipv6;
7784       mp->is_local = is_local;
7785       mp->is_classify = is_classify;
7786       mp->is_multipath = is_multipath;
7787       mp->is_resolve_host = resolve_host;
7788       mp->is_resolve_attached = resolve_attached;
7789       mp->next_hop_weight = next_hop_weight;
7790       mp->dst_address_length = dst_address_length;
7791       mp->next_hop_table_id = ntohl (next_hop_table_id);
7792       mp->classify_table_index = ntohl (classify_table_index);
7793       mp->next_hop_via_label = ntohl (next_hop_via_label);
7794       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7795       if (0 != mp->next_hop_n_out_labels)
7796         {
7797           memcpy (mp->next_hop_out_label_stack,
7798                   next_hop_out_label_stack,
7799                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7800           vec_free (next_hop_out_label_stack);
7801         }
7802
7803       if (is_ipv6)
7804         {
7805           clib_memcpy (mp->dst_address, &v6_dst_address,
7806                        sizeof (v6_dst_address));
7807           if (next_hop_set)
7808             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7809                          sizeof (v6_next_hop_address));
7810           increment_v6_address (&v6_dst_address);
7811         }
7812       else
7813         {
7814           clib_memcpy (mp->dst_address, &v4_dst_address,
7815                        sizeof (v4_dst_address));
7816           if (next_hop_set)
7817             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7818                          sizeof (v4_next_hop_address));
7819           if (random_add_del)
7820             v4_dst_address.as_u32 = random_vector[j + 1];
7821           else
7822             increment_v4_address (&v4_dst_address);
7823         }
7824       /* send it... */
7825       S (mp);
7826       /* If we receive SIGTERM, stop now... */
7827       if (vam->do_exit)
7828         break;
7829     }
7830
7831   /* When testing multiple add/del ops, use a control-ping to sync */
7832   if (count > 1)
7833     {
7834       vl_api_control_ping_t *mp_ping;
7835       f64 after;
7836       f64 timeout;
7837
7838       /* Shut off async mode */
7839       vam->async_mode = 0;
7840
7841       MPING (CONTROL_PING, mp_ping);
7842       S (mp_ping);
7843
7844       timeout = vat_time_now (vam) + 1.0;
7845       while (vat_time_now (vam) < timeout)
7846         if (vam->result_ready == 1)
7847           goto out;
7848       vam->retval = -99;
7849
7850     out:
7851       if (vam->retval == -99)
7852         errmsg ("timeout");
7853
7854       if (vam->async_errors > 0)
7855         {
7856           errmsg ("%d asynchronous errors", vam->async_errors);
7857           vam->retval = -98;
7858         }
7859       vam->async_errors = 0;
7860       after = vat_time_now (vam);
7861
7862       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7863       if (j > 0)
7864         count = j;
7865
7866       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7867              count, after - before, count / (after - before));
7868     }
7869   else
7870     {
7871       int ret;
7872
7873       /* Wait for a reply... */
7874       W (ret);
7875       return ret;
7876     }
7877
7878   /* Return the good/bad news */
7879   return (vam->retval);
7880 }
7881
7882 static int
7883 api_ip_mroute_add_del (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_ip_mroute_add_del_t *mp;
7887   u32 sw_if_index = ~0, vrf_id = 0;
7888   u8 is_ipv6 = 0;
7889   u8 is_local = 0;
7890   u8 create_vrf_if_needed = 0;
7891   u8 is_add = 1;
7892   u8 address_set = 0;
7893   u32 grp_address_length = 0;
7894   ip4_address_t v4_grp_address, v4_src_address;
7895   ip6_address_t v6_grp_address, v6_src_address;
7896   mfib_itf_flags_t iflags = 0;
7897   mfib_entry_flags_t eflags = 0;
7898   int ret;
7899
7900   /* Parse args required to build the message */
7901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7902     {
7903       if (unformat (i, "sw_if_index %d", &sw_if_index))
7904         ;
7905       else if (unformat (i, "%U %U",
7906                          unformat_ip4_address, &v4_src_address,
7907                          unformat_ip4_address, &v4_grp_address))
7908         {
7909           grp_address_length = 64;
7910           address_set = 1;
7911           is_ipv6 = 0;
7912         }
7913       else if (unformat (i, "%U %U",
7914                          unformat_ip6_address, &v6_src_address,
7915                          unformat_ip6_address, &v6_grp_address))
7916         {
7917           grp_address_length = 256;
7918           address_set = 1;
7919           is_ipv6 = 1;
7920         }
7921       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7922         {
7923           memset (&v4_src_address, 0, sizeof (v4_src_address));
7924           grp_address_length = 32;
7925           address_set = 1;
7926           is_ipv6 = 0;
7927         }
7928       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7929         {
7930           memset (&v6_src_address, 0, sizeof (v6_src_address));
7931           grp_address_length = 128;
7932           address_set = 1;
7933           is_ipv6 = 1;
7934         }
7935       else if (unformat (i, "/%d", &grp_address_length))
7936         ;
7937       else if (unformat (i, "local"))
7938         {
7939           is_local = 1;
7940         }
7941       else if (unformat (i, "del"))
7942         is_add = 0;
7943       else if (unformat (i, "add"))
7944         is_add = 1;
7945       else if (unformat (i, "vrf %d", &vrf_id))
7946         ;
7947       else if (unformat (i, "create-vrf"))
7948         create_vrf_if_needed = 1;
7949       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7950         ;
7951       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7952         ;
7953       else
7954         {
7955           clib_warning ("parse error '%U'", format_unformat_error, i);
7956           return -99;
7957         }
7958     }
7959
7960   if (address_set == 0)
7961     {
7962       errmsg ("missing addresses\n");
7963       return -99;
7964     }
7965
7966   /* Construct the API message */
7967   M (IP_MROUTE_ADD_DEL, mp);
7968
7969   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7970   mp->table_id = ntohl (vrf_id);
7971   mp->create_vrf_if_needed = create_vrf_if_needed;
7972
7973   mp->is_add = is_add;
7974   mp->is_ipv6 = is_ipv6;
7975   mp->is_local = is_local;
7976   mp->itf_flags = ntohl (iflags);
7977   mp->entry_flags = ntohl (eflags);
7978   mp->grp_address_length = grp_address_length;
7979   mp->grp_address_length = ntohs (mp->grp_address_length);
7980
7981   if (is_ipv6)
7982     {
7983       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7984       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7985     }
7986   else
7987     {
7988       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7989       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7990
7991     }
7992
7993   /* send it... */
7994   S (mp);
7995   /* Wait for a reply... */
7996   W (ret);
7997   return ret;
7998 }
7999
8000 static int
8001 api_mpls_table_add_del (vat_main_t * vam)
8002 {
8003   unformat_input_t *i = vam->input;
8004   vl_api_mpls_table_add_del_t *mp;
8005   u32 table_id = ~0;
8006   u8 is_add = 1;
8007   int ret = 0;
8008
8009   /* Parse args required to build the message */
8010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8011     {
8012       if (unformat (i, "table %d", &table_id))
8013         ;
8014       else if (unformat (i, "del"))
8015         is_add = 0;
8016       else if (unformat (i, "add"))
8017         is_add = 1;
8018       else
8019         {
8020           clib_warning ("parse error '%U'", format_unformat_error, i);
8021           return -99;
8022         }
8023     }
8024
8025   if (~0 == table_id)
8026     {
8027       errmsg ("missing table-ID");
8028       return -99;
8029     }
8030
8031   /* Construct the API message */
8032   M (MPLS_TABLE_ADD_DEL, mp);
8033
8034   mp->mt_table_id = ntohl (table_id);
8035   mp->mt_is_add = is_add;
8036
8037   /* send it... */
8038   S (mp);
8039
8040   /* Wait for a reply... */
8041   W (ret);
8042
8043   return ret;
8044 }
8045
8046 static int
8047 api_mpls_route_add_del (vat_main_t * vam)
8048 {
8049   unformat_input_t *i = vam->input;
8050   vl_api_mpls_route_add_del_t *mp;
8051   u32 sw_if_index = ~0, table_id = 0;
8052   u8 create_table_if_needed = 0;
8053   u8 is_add = 1;
8054   u32 next_hop_weight = 1;
8055   u8 is_multipath = 0;
8056   u32 next_hop_table_id = 0;
8057   u8 next_hop_set = 0;
8058   ip4_address_t v4_next_hop_address = {
8059     .as_u32 = 0,
8060   };
8061   ip6_address_t v6_next_hop_address = { {0} };
8062   int count = 1;
8063   int j;
8064   f64 before = 0;
8065   u32 classify_table_index = ~0;
8066   u8 is_classify = 0;
8067   u8 resolve_host = 0, resolve_attached = 0;
8068   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8069   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8070   mpls_label_t *next_hop_out_label_stack = NULL;
8071   mpls_label_t local_label = MPLS_LABEL_INVALID;
8072   u8 is_eos = 0;
8073   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8074
8075   /* Parse args required to build the message */
8076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8077     {
8078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8079         ;
8080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8081         ;
8082       else if (unformat (i, "%d", &local_label))
8083         ;
8084       else if (unformat (i, "eos"))
8085         is_eos = 1;
8086       else if (unformat (i, "non-eos"))
8087         is_eos = 0;
8088       else if (unformat (i, "via %U", unformat_ip4_address,
8089                          &v4_next_hop_address))
8090         {
8091           next_hop_set = 1;
8092           next_hop_proto = DPO_PROTO_IP4;
8093         }
8094       else if (unformat (i, "via %U", unformat_ip6_address,
8095                          &v6_next_hop_address))
8096         {
8097           next_hop_set = 1;
8098           next_hop_proto = DPO_PROTO_IP6;
8099         }
8100       else if (unformat (i, "weight %d", &next_hop_weight))
8101         ;
8102       else if (unformat (i, "create-table"))
8103         create_table_if_needed = 1;
8104       else if (unformat (i, "classify %d", &classify_table_index))
8105         {
8106           is_classify = 1;
8107         }
8108       else if (unformat (i, "del"))
8109         is_add = 0;
8110       else if (unformat (i, "add"))
8111         is_add = 1;
8112       else if (unformat (i, "resolve-via-host"))
8113         resolve_host = 1;
8114       else if (unformat (i, "resolve-via-attached"))
8115         resolve_attached = 1;
8116       else if (unformat (i, "multipath"))
8117         is_multipath = 1;
8118       else if (unformat (i, "count %d", &count))
8119         ;
8120       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8121         {
8122           next_hop_set = 1;
8123           next_hop_proto = DPO_PROTO_IP4;
8124         }
8125       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8126         {
8127           next_hop_set = 1;
8128           next_hop_proto = DPO_PROTO_IP6;
8129         }
8130       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8131         ;
8132       else if (unformat (i, "via-label %d", &next_hop_via_label))
8133         ;
8134       else if (unformat (i, "out-label %d", &next_hop_out_label))
8135         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8136       else
8137         {
8138           clib_warning ("parse error '%U'", format_unformat_error, i);
8139           return -99;
8140         }
8141     }
8142
8143   if (!next_hop_set && !is_classify)
8144     {
8145       errmsg ("next hop / classify not set");
8146       return -99;
8147     }
8148
8149   if (MPLS_LABEL_INVALID == local_label)
8150     {
8151       errmsg ("missing label");
8152       return -99;
8153     }
8154
8155   if (count > 1)
8156     {
8157       /* Turn on async mode */
8158       vam->async_mode = 1;
8159       vam->async_errors = 0;
8160       before = vat_time_now (vam);
8161     }
8162
8163   for (j = 0; j < count; j++)
8164     {
8165       /* Construct the API message */
8166       M2 (MPLS_ROUTE_ADD_DEL, mp,
8167           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8168
8169       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8170       mp->mr_table_id = ntohl (table_id);
8171       mp->mr_create_table_if_needed = create_table_if_needed;
8172
8173       mp->mr_is_add = is_add;
8174       mp->mr_next_hop_proto = next_hop_proto;
8175       mp->mr_is_classify = is_classify;
8176       mp->mr_is_multipath = is_multipath;
8177       mp->mr_is_resolve_host = resolve_host;
8178       mp->mr_is_resolve_attached = resolve_attached;
8179       mp->mr_next_hop_weight = next_hop_weight;
8180       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8181       mp->mr_classify_table_index = ntohl (classify_table_index);
8182       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8183       mp->mr_label = ntohl (local_label);
8184       mp->mr_eos = is_eos;
8185
8186       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8187       if (0 != mp->mr_next_hop_n_out_labels)
8188         {
8189           memcpy (mp->mr_next_hop_out_label_stack,
8190                   next_hop_out_label_stack,
8191                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8192           vec_free (next_hop_out_label_stack);
8193         }
8194
8195       if (next_hop_set)
8196         {
8197           if (DPO_PROTO_IP4 == next_hop_proto)
8198             {
8199               clib_memcpy (mp->mr_next_hop,
8200                            &v4_next_hop_address,
8201                            sizeof (v4_next_hop_address));
8202             }
8203           else if (DPO_PROTO_IP6 == next_hop_proto)
8204
8205             {
8206               clib_memcpy (mp->mr_next_hop,
8207                            &v6_next_hop_address,
8208                            sizeof (v6_next_hop_address));
8209             }
8210         }
8211       local_label++;
8212
8213       /* send it... */
8214       S (mp);
8215       /* If we receive SIGTERM, stop now... */
8216       if (vam->do_exit)
8217         break;
8218     }
8219
8220   /* When testing multiple add/del ops, use a control-ping to sync */
8221   if (count > 1)
8222     {
8223       vl_api_control_ping_t *mp_ping;
8224       f64 after;
8225       f64 timeout;
8226
8227       /* Shut off async mode */
8228       vam->async_mode = 0;
8229
8230       MPING (CONTROL_PING, mp_ping);
8231       S (mp_ping);
8232
8233       timeout = vat_time_now (vam) + 1.0;
8234       while (vat_time_now (vam) < timeout)
8235         if (vam->result_ready == 1)
8236           goto out;
8237       vam->retval = -99;
8238
8239     out:
8240       if (vam->retval == -99)
8241         errmsg ("timeout");
8242
8243       if (vam->async_errors > 0)
8244         {
8245           errmsg ("%d asynchronous errors", vam->async_errors);
8246           vam->retval = -98;
8247         }
8248       vam->async_errors = 0;
8249       after = vat_time_now (vam);
8250
8251       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8252       if (j > 0)
8253         count = j;
8254
8255       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8256              count, after - before, count / (after - before));
8257     }
8258   else
8259     {
8260       int ret;
8261
8262       /* Wait for a reply... */
8263       W (ret);
8264       return ret;
8265     }
8266
8267   /* Return the good/bad news */
8268   return (vam->retval);
8269 }
8270
8271 static int
8272 api_mpls_ip_bind_unbind (vat_main_t * vam)
8273 {
8274   unformat_input_t *i = vam->input;
8275   vl_api_mpls_ip_bind_unbind_t *mp;
8276   u32 ip_table_id = 0;
8277   u8 create_table_if_needed = 0;
8278   u8 is_bind = 1;
8279   u8 is_ip4 = 1;
8280   ip4_address_t v4_address;
8281   ip6_address_t v6_address;
8282   u32 address_length;
8283   u8 address_set = 0;
8284   mpls_label_t local_label = MPLS_LABEL_INVALID;
8285   int ret;
8286
8287   /* Parse args required to build the message */
8288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8289     {
8290       if (unformat (i, "%U/%d", unformat_ip4_address,
8291                     &v4_address, &address_length))
8292         {
8293           is_ip4 = 1;
8294           address_set = 1;
8295         }
8296       else if (unformat (i, "%U/%d", unformat_ip6_address,
8297                          &v6_address, &address_length))
8298         {
8299           is_ip4 = 0;
8300           address_set = 1;
8301         }
8302       else if (unformat (i, "%d", &local_label))
8303         ;
8304       else if (unformat (i, "create-table"))
8305         create_table_if_needed = 1;
8306       else if (unformat (i, "table-id %d", &ip_table_id))
8307         ;
8308       else if (unformat (i, "unbind"))
8309         is_bind = 0;
8310       else if (unformat (i, "bind"))
8311         is_bind = 1;
8312       else
8313         {
8314           clib_warning ("parse error '%U'", format_unformat_error, i);
8315           return -99;
8316         }
8317     }
8318
8319   if (!address_set)
8320     {
8321       errmsg ("IP addres not set");
8322       return -99;
8323     }
8324
8325   if (MPLS_LABEL_INVALID == local_label)
8326     {
8327       errmsg ("missing label");
8328       return -99;
8329     }
8330
8331   /* Construct the API message */
8332   M (MPLS_IP_BIND_UNBIND, mp);
8333
8334   mp->mb_create_table_if_needed = create_table_if_needed;
8335   mp->mb_is_bind = is_bind;
8336   mp->mb_is_ip4 = is_ip4;
8337   mp->mb_ip_table_id = ntohl (ip_table_id);
8338   mp->mb_mpls_table_id = 0;
8339   mp->mb_label = ntohl (local_label);
8340   mp->mb_address_length = address_length;
8341
8342   if (is_ip4)
8343     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8344   else
8345     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8346
8347   /* send it... */
8348   S (mp);
8349
8350   /* Wait for a reply... */
8351   W (ret);
8352   return ret;
8353 }
8354
8355 static int
8356 api_proxy_arp_add_del (vat_main_t * vam)
8357 {
8358   unformat_input_t *i = vam->input;
8359   vl_api_proxy_arp_add_del_t *mp;
8360   u32 vrf_id = 0;
8361   u8 is_add = 1;
8362   ip4_address_t lo, hi;
8363   u8 range_set = 0;
8364   int ret;
8365
8366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8367     {
8368       if (unformat (i, "vrf %d", &vrf_id))
8369         ;
8370       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8371                          unformat_ip4_address, &hi))
8372         range_set = 1;
8373       else if (unformat (i, "del"))
8374         is_add = 0;
8375       else
8376         {
8377           clib_warning ("parse error '%U'", format_unformat_error, i);
8378           return -99;
8379         }
8380     }
8381
8382   if (range_set == 0)
8383     {
8384       errmsg ("address range not set");
8385       return -99;
8386     }
8387
8388   M (PROXY_ARP_ADD_DEL, mp);
8389
8390   mp->vrf_id = ntohl (vrf_id);
8391   mp->is_add = is_add;
8392   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8393   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8394
8395   S (mp);
8396   W (ret);
8397   return ret;
8398 }
8399
8400 static int
8401 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8402 {
8403   unformat_input_t *i = vam->input;
8404   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8405   u32 sw_if_index;
8406   u8 enable = 1;
8407   u8 sw_if_index_set = 0;
8408   int ret;
8409
8410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8411     {
8412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8413         sw_if_index_set = 1;
8414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8415         sw_if_index_set = 1;
8416       else if (unformat (i, "enable"))
8417         enable = 1;
8418       else if (unformat (i, "disable"))
8419         enable = 0;
8420       else
8421         {
8422           clib_warning ("parse error '%U'", format_unformat_error, i);
8423           return -99;
8424         }
8425     }
8426
8427   if (sw_if_index_set == 0)
8428     {
8429       errmsg ("missing interface name or sw_if_index");
8430       return -99;
8431     }
8432
8433   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8434
8435   mp->sw_if_index = ntohl (sw_if_index);
8436   mp->enable_disable = enable;
8437
8438   S (mp);
8439   W (ret);
8440   return ret;
8441 }
8442
8443 static int
8444 api_mpls_tunnel_add_del (vat_main_t * vam)
8445 {
8446   unformat_input_t *i = vam->input;
8447   vl_api_mpls_tunnel_add_del_t *mp;
8448
8449   u8 is_add = 1;
8450   u8 l2_only = 0;
8451   u32 sw_if_index = ~0;
8452   u32 next_hop_sw_if_index = ~0;
8453   u32 next_hop_proto_is_ip4 = 1;
8454
8455   u32 next_hop_table_id = 0;
8456   ip4_address_t v4_next_hop_address = {
8457     .as_u32 = 0,
8458   };
8459   ip6_address_t v6_next_hop_address = { {0} };
8460   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8461   int ret;
8462
8463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8464     {
8465       if (unformat (i, "add"))
8466         is_add = 1;
8467       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8468         is_add = 0;
8469       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8470         ;
8471       else if (unformat (i, "via %U",
8472                          unformat_ip4_address, &v4_next_hop_address))
8473         {
8474           next_hop_proto_is_ip4 = 1;
8475         }
8476       else if (unformat (i, "via %U",
8477                          unformat_ip6_address, &v6_next_hop_address))
8478         {
8479           next_hop_proto_is_ip4 = 0;
8480         }
8481       else if (unformat (i, "l2-only"))
8482         l2_only = 1;
8483       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8484         ;
8485       else if (unformat (i, "out-label %d", &next_hop_out_label))
8486         vec_add1 (labels, ntohl (next_hop_out_label));
8487       else
8488         {
8489           clib_warning ("parse error '%U'", format_unformat_error, i);
8490           return -99;
8491         }
8492     }
8493
8494   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8495
8496   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8497   mp->mt_sw_if_index = ntohl (sw_if_index);
8498   mp->mt_is_add = is_add;
8499   mp->mt_l2_only = l2_only;
8500   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8501   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8502
8503   mp->mt_next_hop_n_out_labels = vec_len (labels);
8504
8505   if (0 != mp->mt_next_hop_n_out_labels)
8506     {
8507       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8508                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8509       vec_free (labels);
8510     }
8511
8512   if (next_hop_proto_is_ip4)
8513     {
8514       clib_memcpy (mp->mt_next_hop,
8515                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8516     }
8517   else
8518     {
8519       clib_memcpy (mp->mt_next_hop,
8520                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8521     }
8522
8523   S (mp);
8524   W (ret);
8525   return ret;
8526 }
8527
8528 static int
8529 api_sw_interface_set_unnumbered (vat_main_t * vam)
8530 {
8531   unformat_input_t *i = vam->input;
8532   vl_api_sw_interface_set_unnumbered_t *mp;
8533   u32 sw_if_index;
8534   u32 unnum_sw_index = ~0;
8535   u8 is_add = 1;
8536   u8 sw_if_index_set = 0;
8537   int ret;
8538
8539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8540     {
8541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8542         sw_if_index_set = 1;
8543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8544         sw_if_index_set = 1;
8545       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8546         ;
8547       else if (unformat (i, "del"))
8548         is_add = 0;
8549       else
8550         {
8551           clib_warning ("parse error '%U'", format_unformat_error, i);
8552           return -99;
8553         }
8554     }
8555
8556   if (sw_if_index_set == 0)
8557     {
8558       errmsg ("missing interface name or sw_if_index");
8559       return -99;
8560     }
8561
8562   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8563
8564   mp->sw_if_index = ntohl (sw_if_index);
8565   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8566   mp->is_add = is_add;
8567
8568   S (mp);
8569   W (ret);
8570   return ret;
8571 }
8572
8573 static int
8574 api_ip_neighbor_add_del (vat_main_t * vam)
8575 {
8576   unformat_input_t *i = vam->input;
8577   vl_api_ip_neighbor_add_del_t *mp;
8578   u32 sw_if_index;
8579   u8 sw_if_index_set = 0;
8580   u8 is_add = 1;
8581   u8 is_static = 0;
8582   u8 is_no_fib_entry = 0;
8583   u8 mac_address[6];
8584   u8 mac_set = 0;
8585   u8 v4_address_set = 0;
8586   u8 v6_address_set = 0;
8587   ip4_address_t v4address;
8588   ip6_address_t v6address;
8589   int ret;
8590
8591   memset (mac_address, 0, sizeof (mac_address));
8592
8593   /* Parse args required to build the message */
8594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8595     {
8596       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8597         {
8598           mac_set = 1;
8599         }
8600       else if (unformat (i, "del"))
8601         is_add = 0;
8602       else
8603         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8604         sw_if_index_set = 1;
8605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8606         sw_if_index_set = 1;
8607       else if (unformat (i, "is_static"))
8608         is_static = 1;
8609       else if (unformat (i, "no-fib-entry"))
8610         is_no_fib_entry = 1;
8611       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8612         v4_address_set = 1;
8613       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8614         v6_address_set = 1;
8615       else
8616         {
8617           clib_warning ("parse error '%U'", format_unformat_error, i);
8618           return -99;
8619         }
8620     }
8621
8622   if (sw_if_index_set == 0)
8623     {
8624       errmsg ("missing interface name or sw_if_index");
8625       return -99;
8626     }
8627   if (v4_address_set && v6_address_set)
8628     {
8629       errmsg ("both v4 and v6 addresses set");
8630       return -99;
8631     }
8632   if (!v4_address_set && !v6_address_set)
8633     {
8634       errmsg ("no address set");
8635       return -99;
8636     }
8637
8638   /* Construct the API message */
8639   M (IP_NEIGHBOR_ADD_DEL, mp);
8640
8641   mp->sw_if_index = ntohl (sw_if_index);
8642   mp->is_add = is_add;
8643   mp->is_static = is_static;
8644   mp->is_no_adj_fib = is_no_fib_entry;
8645   if (mac_set)
8646     clib_memcpy (mp->mac_address, mac_address, 6);
8647   if (v6_address_set)
8648     {
8649       mp->is_ipv6 = 1;
8650       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8651     }
8652   else
8653     {
8654       /* mp->is_ipv6 = 0; via memset in M macro above */
8655       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8656     }
8657
8658   /* send it... */
8659   S (mp);
8660
8661   /* Wait for a reply, return good/bad news  */
8662   W (ret);
8663   return ret;
8664 }
8665
8666 static int
8667 api_reset_vrf (vat_main_t * vam)
8668 {
8669   unformat_input_t *i = vam->input;
8670   vl_api_reset_vrf_t *mp;
8671   u32 vrf_id = 0;
8672   u8 is_ipv6 = 0;
8673   u8 vrf_id_set = 0;
8674   int ret;
8675
8676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8677     {
8678       if (unformat (i, "vrf %d", &vrf_id))
8679         vrf_id_set = 1;
8680       else if (unformat (i, "ipv6"))
8681         is_ipv6 = 1;
8682       else
8683         {
8684           clib_warning ("parse error '%U'", format_unformat_error, i);
8685           return -99;
8686         }
8687     }
8688
8689   if (vrf_id_set == 0)
8690     {
8691       errmsg ("missing vrf id");
8692       return -99;
8693     }
8694
8695   M (RESET_VRF, mp);
8696
8697   mp->vrf_id = ntohl (vrf_id);
8698   mp->is_ipv6 = is_ipv6;
8699
8700   S (mp);
8701   W (ret);
8702   return ret;
8703 }
8704
8705 static int
8706 api_create_vlan_subif (vat_main_t * vam)
8707 {
8708   unformat_input_t *i = vam->input;
8709   vl_api_create_vlan_subif_t *mp;
8710   u32 sw_if_index;
8711   u8 sw_if_index_set = 0;
8712   u32 vlan_id;
8713   u8 vlan_id_set = 0;
8714   int ret;
8715
8716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8717     {
8718       if (unformat (i, "sw_if_index %d", &sw_if_index))
8719         sw_if_index_set = 1;
8720       else
8721         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8722         sw_if_index_set = 1;
8723       else if (unformat (i, "vlan %d", &vlan_id))
8724         vlan_id_set = 1;
8725       else
8726         {
8727           clib_warning ("parse error '%U'", format_unformat_error, i);
8728           return -99;
8729         }
8730     }
8731
8732   if (sw_if_index_set == 0)
8733     {
8734       errmsg ("missing interface name or sw_if_index");
8735       return -99;
8736     }
8737
8738   if (vlan_id_set == 0)
8739     {
8740       errmsg ("missing vlan_id");
8741       return -99;
8742     }
8743   M (CREATE_VLAN_SUBIF, mp);
8744
8745   mp->sw_if_index = ntohl (sw_if_index);
8746   mp->vlan_id = ntohl (vlan_id);
8747
8748   S (mp);
8749   W (ret);
8750   return ret;
8751 }
8752
8753 #define foreach_create_subif_bit                \
8754 _(no_tags)                                      \
8755 _(one_tag)                                      \
8756 _(two_tags)                                     \
8757 _(dot1ad)                                       \
8758 _(exact_match)                                  \
8759 _(default_sub)                                  \
8760 _(outer_vlan_id_any)                            \
8761 _(inner_vlan_id_any)
8762
8763 static int
8764 api_create_subif (vat_main_t * vam)
8765 {
8766   unformat_input_t *i = vam->input;
8767   vl_api_create_subif_t *mp;
8768   u32 sw_if_index;
8769   u8 sw_if_index_set = 0;
8770   u32 sub_id;
8771   u8 sub_id_set = 0;
8772   u32 no_tags = 0;
8773   u32 one_tag = 0;
8774   u32 two_tags = 0;
8775   u32 dot1ad = 0;
8776   u32 exact_match = 0;
8777   u32 default_sub = 0;
8778   u32 outer_vlan_id_any = 0;
8779   u32 inner_vlan_id_any = 0;
8780   u32 tmp;
8781   u16 outer_vlan_id = 0;
8782   u16 inner_vlan_id = 0;
8783   int ret;
8784
8785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8786     {
8787       if (unformat (i, "sw_if_index %d", &sw_if_index))
8788         sw_if_index_set = 1;
8789       else
8790         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8791         sw_if_index_set = 1;
8792       else if (unformat (i, "sub_id %d", &sub_id))
8793         sub_id_set = 1;
8794       else if (unformat (i, "outer_vlan_id %d", &tmp))
8795         outer_vlan_id = tmp;
8796       else if (unformat (i, "inner_vlan_id %d", &tmp))
8797         inner_vlan_id = tmp;
8798
8799 #define _(a) else if (unformat (i, #a)) a = 1 ;
8800       foreach_create_subif_bit
8801 #undef _
8802         else
8803         {
8804           clib_warning ("parse error '%U'", format_unformat_error, i);
8805           return -99;
8806         }
8807     }
8808
8809   if (sw_if_index_set == 0)
8810     {
8811       errmsg ("missing interface name or sw_if_index");
8812       return -99;
8813     }
8814
8815   if (sub_id_set == 0)
8816     {
8817       errmsg ("missing sub_id");
8818       return -99;
8819     }
8820   M (CREATE_SUBIF, mp);
8821
8822   mp->sw_if_index = ntohl (sw_if_index);
8823   mp->sub_id = ntohl (sub_id);
8824
8825 #define _(a) mp->a = a;
8826   foreach_create_subif_bit;
8827 #undef _
8828
8829   mp->outer_vlan_id = ntohs (outer_vlan_id);
8830   mp->inner_vlan_id = ntohs (inner_vlan_id);
8831
8832   S (mp);
8833   W (ret);
8834   return ret;
8835 }
8836
8837 static int
8838 api_oam_add_del (vat_main_t * vam)
8839 {
8840   unformat_input_t *i = vam->input;
8841   vl_api_oam_add_del_t *mp;
8842   u32 vrf_id = 0;
8843   u8 is_add = 1;
8844   ip4_address_t src, dst;
8845   u8 src_set = 0;
8846   u8 dst_set = 0;
8847   int ret;
8848
8849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8850     {
8851       if (unformat (i, "vrf %d", &vrf_id))
8852         ;
8853       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8854         src_set = 1;
8855       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8856         dst_set = 1;
8857       else if (unformat (i, "del"))
8858         is_add = 0;
8859       else
8860         {
8861           clib_warning ("parse error '%U'", format_unformat_error, i);
8862           return -99;
8863         }
8864     }
8865
8866   if (src_set == 0)
8867     {
8868       errmsg ("missing src addr");
8869       return -99;
8870     }
8871
8872   if (dst_set == 0)
8873     {
8874       errmsg ("missing dst addr");
8875       return -99;
8876     }
8877
8878   M (OAM_ADD_DEL, mp);
8879
8880   mp->vrf_id = ntohl (vrf_id);
8881   mp->is_add = is_add;
8882   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8883   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8884
8885   S (mp);
8886   W (ret);
8887   return ret;
8888 }
8889
8890 static int
8891 api_reset_fib (vat_main_t * vam)
8892 {
8893   unformat_input_t *i = vam->input;
8894   vl_api_reset_fib_t *mp;
8895   u32 vrf_id = 0;
8896   u8 is_ipv6 = 0;
8897   u8 vrf_id_set = 0;
8898
8899   int ret;
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "vrf %d", &vrf_id))
8903         vrf_id_set = 1;
8904       else if (unformat (i, "ipv6"))
8905         is_ipv6 = 1;
8906       else
8907         {
8908           clib_warning ("parse error '%U'", format_unformat_error, i);
8909           return -99;
8910         }
8911     }
8912
8913   if (vrf_id_set == 0)
8914     {
8915       errmsg ("missing vrf id");
8916       return -99;
8917     }
8918
8919   M (RESET_FIB, mp);
8920
8921   mp->vrf_id = ntohl (vrf_id);
8922   mp->is_ipv6 = is_ipv6;
8923
8924   S (mp);
8925   W (ret);
8926   return ret;
8927 }
8928
8929 static int
8930 api_dhcp_proxy_config (vat_main_t * vam)
8931 {
8932   unformat_input_t *i = vam->input;
8933   vl_api_dhcp_proxy_config_t *mp;
8934   u32 rx_vrf_id = 0;
8935   u32 server_vrf_id = 0;
8936   u8 is_add = 1;
8937   u8 v4_address_set = 0;
8938   u8 v6_address_set = 0;
8939   ip4_address_t v4address;
8940   ip6_address_t v6address;
8941   u8 v4_src_address_set = 0;
8942   u8 v6_src_address_set = 0;
8943   ip4_address_t v4srcaddress;
8944   ip6_address_t v6srcaddress;
8945   int ret;
8946
8947   /* Parse args required to build the message */
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "del"))
8951         is_add = 0;
8952       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8953         ;
8954       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8955         ;
8956       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8957         v4_address_set = 1;
8958       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8959         v6_address_set = 1;
8960       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8961         v4_src_address_set = 1;
8962       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8963         v6_src_address_set = 1;
8964       else
8965         break;
8966     }
8967
8968   if (v4_address_set && v6_address_set)
8969     {
8970       errmsg ("both v4 and v6 server addresses set");
8971       return -99;
8972     }
8973   if (!v4_address_set && !v6_address_set)
8974     {
8975       errmsg ("no server addresses set");
8976       return -99;
8977     }
8978
8979   if (v4_src_address_set && v6_src_address_set)
8980     {
8981       errmsg ("both v4 and v6  src addresses set");
8982       return -99;
8983     }
8984   if (!v4_src_address_set && !v6_src_address_set)
8985     {
8986       errmsg ("no src addresses set");
8987       return -99;
8988     }
8989
8990   if (!(v4_src_address_set && v4_address_set) &&
8991       !(v6_src_address_set && v6_address_set))
8992     {
8993       errmsg ("no matching server and src addresses set");
8994       return -99;
8995     }
8996
8997   /* Construct the API message */
8998   M (DHCP_PROXY_CONFIG, mp);
8999
9000   mp->is_add = is_add;
9001   mp->rx_vrf_id = ntohl (rx_vrf_id);
9002   mp->server_vrf_id = ntohl (server_vrf_id);
9003   if (v6_address_set)
9004     {
9005       mp->is_ipv6 = 1;
9006       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9007       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9008     }
9009   else
9010     {
9011       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9012       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9013     }
9014
9015   /* send it... */
9016   S (mp);
9017
9018   /* Wait for a reply, return good/bad news  */
9019   W (ret);
9020   return ret;
9021 }
9022
9023 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9024 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9025
9026 static void
9027 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9028 {
9029   vat_main_t *vam = &vat_main;
9030   u32 i, count = mp->count;
9031   vl_api_dhcp_server_t *s;
9032
9033   if (mp->is_ipv6)
9034     print (vam->ofp,
9035            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9036            ntohl (mp->rx_vrf_id),
9037            format_ip6_address, mp->dhcp_src_address,
9038            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9039   else
9040     print (vam->ofp,
9041            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9042            ntohl (mp->rx_vrf_id),
9043            format_ip4_address, mp->dhcp_src_address,
9044            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9045
9046   for (i = 0; i < count; i++)
9047     {
9048       s = &mp->servers[i];
9049
9050       if (mp->is_ipv6)
9051         print (vam->ofp,
9052                " Server Table-ID %d, Server Address %U",
9053                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9054       else
9055         print (vam->ofp,
9056                " Server Table-ID %d, Server Address %U",
9057                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9058     }
9059 }
9060
9061 static void vl_api_dhcp_proxy_details_t_handler_json
9062   (vl_api_dhcp_proxy_details_t * mp)
9063 {
9064   vat_main_t *vam = &vat_main;
9065   vat_json_node_t *node = NULL;
9066   u32 i, count = mp->count;
9067   struct in_addr ip4;
9068   struct in6_addr ip6;
9069   vl_api_dhcp_server_t *s;
9070
9071   if (VAT_JSON_ARRAY != vam->json_tree.type)
9072     {
9073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9074       vat_json_init_array (&vam->json_tree);
9075     }
9076   node = vat_json_array_add (&vam->json_tree);
9077
9078   vat_json_init_object (node);
9079   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9080   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9081   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9082
9083   if (mp->is_ipv6)
9084     {
9085       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9086       vat_json_object_add_ip6 (node, "src_address", ip6);
9087     }
9088   else
9089     {
9090       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9091       vat_json_object_add_ip4 (node, "src_address", ip4);
9092     }
9093
9094   for (i = 0; i < count; i++)
9095     {
9096       s = &mp->servers[i];
9097
9098       vat_json_object_add_uint (node, "server-table-id",
9099                                 ntohl (s->server_vrf_id));
9100
9101       if (mp->is_ipv6)
9102         {
9103           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9104           vat_json_object_add_ip4 (node, "src_address", ip4);
9105         }
9106       else
9107         {
9108           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9109           vat_json_object_add_ip6 (node, "server_address", ip6);
9110         }
9111     }
9112 }
9113
9114 static int
9115 api_dhcp_proxy_dump (vat_main_t * vam)
9116 {
9117   unformat_input_t *i = vam->input;
9118   vl_api_control_ping_t *mp_ping;
9119   vl_api_dhcp_proxy_dump_t *mp;
9120   u8 is_ipv6 = 0;
9121   int ret;
9122
9123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9124     {
9125       if (unformat (i, "ipv6"))
9126         is_ipv6 = 1;
9127       else
9128         {
9129           clib_warning ("parse error '%U'", format_unformat_error, i);
9130           return -99;
9131         }
9132     }
9133
9134   M (DHCP_PROXY_DUMP, mp);
9135
9136   mp->is_ip6 = is_ipv6;
9137   S (mp);
9138
9139   /* Use a control ping for synchronization */
9140   MPING (CONTROL_PING, mp_ping);
9141   S (mp_ping);
9142
9143   W (ret);
9144   return ret;
9145 }
9146
9147 static int
9148 api_dhcp_proxy_set_vss (vat_main_t * vam)
9149 {
9150   unformat_input_t *i = vam->input;
9151   vl_api_dhcp_proxy_set_vss_t *mp;
9152   u8 is_ipv6 = 0;
9153   u8 is_add = 1;
9154   u32 tbl_id;
9155   u8 tbl_id_set = 0;
9156   u32 oui;
9157   u8 oui_set = 0;
9158   u32 fib_id;
9159   u8 fib_id_set = 0;
9160   int ret;
9161
9162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9163     {
9164       if (unformat (i, "tbl_id %d", &tbl_id))
9165         tbl_id_set = 1;
9166       if (unformat (i, "fib_id %d", &fib_id))
9167         fib_id_set = 1;
9168       if (unformat (i, "oui %d", &oui))
9169         oui_set = 1;
9170       else if (unformat (i, "ipv6"))
9171         is_ipv6 = 1;
9172       else if (unformat (i, "del"))
9173         is_add = 0;
9174       else
9175         {
9176           clib_warning ("parse error '%U'", format_unformat_error, i);
9177           return -99;
9178         }
9179     }
9180
9181   if (tbl_id_set == 0)
9182     {
9183       errmsg ("missing tbl id");
9184       return -99;
9185     }
9186
9187   if (fib_id_set == 0)
9188     {
9189       errmsg ("missing fib id");
9190       return -99;
9191     }
9192   if (oui_set == 0)
9193     {
9194       errmsg ("missing oui");
9195       return -99;
9196     }
9197
9198   M (DHCP_PROXY_SET_VSS, mp);
9199   mp->tbl_id = ntohl (tbl_id);
9200   mp->fib_id = ntohl (fib_id);
9201   mp->oui = ntohl (oui);
9202   mp->is_ipv6 = is_ipv6;
9203   mp->is_add = is_add;
9204
9205   S (mp);
9206   W (ret);
9207   return ret;
9208 }
9209
9210 static int
9211 api_dhcp_client_config (vat_main_t * vam)
9212 {
9213   unformat_input_t *i = vam->input;
9214   vl_api_dhcp_client_config_t *mp;
9215   u32 sw_if_index;
9216   u8 sw_if_index_set = 0;
9217   u8 is_add = 1;
9218   u8 *hostname = 0;
9219   u8 disable_event = 0;
9220   int ret;
9221
9222   /* Parse args required to build the message */
9223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9224     {
9225       if (unformat (i, "del"))
9226         is_add = 0;
9227       else
9228         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9229         sw_if_index_set = 1;
9230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9231         sw_if_index_set = 1;
9232       else if (unformat (i, "hostname %s", &hostname))
9233         ;
9234       else if (unformat (i, "disable_event"))
9235         disable_event = 1;
9236       else
9237         break;
9238     }
9239
9240   if (sw_if_index_set == 0)
9241     {
9242       errmsg ("missing interface name or sw_if_index");
9243       return -99;
9244     }
9245
9246   if (vec_len (hostname) > 63)
9247     {
9248       errmsg ("hostname too long");
9249     }
9250   vec_add1 (hostname, 0);
9251
9252   /* Construct the API message */
9253   M (DHCP_CLIENT_CONFIG, mp);
9254
9255   mp->sw_if_index = htonl (sw_if_index);
9256   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9257   vec_free (hostname);
9258   mp->is_add = is_add;
9259   mp->want_dhcp_event = disable_event ? 0 : 1;
9260   mp->pid = htonl (getpid ());
9261
9262   /* send it... */
9263   S (mp);
9264
9265   /* Wait for a reply, return good/bad news  */
9266   W (ret);
9267   return ret;
9268 }
9269
9270 static int
9271 api_set_ip_flow_hash (vat_main_t * vam)
9272 {
9273   unformat_input_t *i = vam->input;
9274   vl_api_set_ip_flow_hash_t *mp;
9275   u32 vrf_id = 0;
9276   u8 is_ipv6 = 0;
9277   u8 vrf_id_set = 0;
9278   u8 src = 0;
9279   u8 dst = 0;
9280   u8 sport = 0;
9281   u8 dport = 0;
9282   u8 proto = 0;
9283   u8 reverse = 0;
9284   int ret;
9285
9286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9287     {
9288       if (unformat (i, "vrf %d", &vrf_id))
9289         vrf_id_set = 1;
9290       else if (unformat (i, "ipv6"))
9291         is_ipv6 = 1;
9292       else if (unformat (i, "src"))
9293         src = 1;
9294       else if (unformat (i, "dst"))
9295         dst = 1;
9296       else if (unformat (i, "sport"))
9297         sport = 1;
9298       else if (unformat (i, "dport"))
9299         dport = 1;
9300       else if (unformat (i, "proto"))
9301         proto = 1;
9302       else if (unformat (i, "reverse"))
9303         reverse = 1;
9304
9305       else
9306         {
9307           clib_warning ("parse error '%U'", format_unformat_error, i);
9308           return -99;
9309         }
9310     }
9311
9312   if (vrf_id_set == 0)
9313     {
9314       errmsg ("missing vrf id");
9315       return -99;
9316     }
9317
9318   M (SET_IP_FLOW_HASH, mp);
9319   mp->src = src;
9320   mp->dst = dst;
9321   mp->sport = sport;
9322   mp->dport = dport;
9323   mp->proto = proto;
9324   mp->reverse = reverse;
9325   mp->vrf_id = ntohl (vrf_id);
9326   mp->is_ipv6 = is_ipv6;
9327
9328   S (mp);
9329   W (ret);
9330   return ret;
9331 }
9332
9333 static int
9334 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9335 {
9336   unformat_input_t *i = vam->input;
9337   vl_api_sw_interface_ip6_enable_disable_t *mp;
9338   u32 sw_if_index;
9339   u8 sw_if_index_set = 0;
9340   u8 enable = 0;
9341   int ret;
9342
9343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9344     {
9345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9346         sw_if_index_set = 1;
9347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9348         sw_if_index_set = 1;
9349       else if (unformat (i, "enable"))
9350         enable = 1;
9351       else if (unformat (i, "disable"))
9352         enable = 0;
9353       else
9354         {
9355           clib_warning ("parse error '%U'", format_unformat_error, i);
9356           return -99;
9357         }
9358     }
9359
9360   if (sw_if_index_set == 0)
9361     {
9362       errmsg ("missing interface name or sw_if_index");
9363       return -99;
9364     }
9365
9366   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9367
9368   mp->sw_if_index = ntohl (sw_if_index);
9369   mp->enable = enable;
9370
9371   S (mp);
9372   W (ret);
9373   return ret;
9374 }
9375
9376 static int
9377 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9378 {
9379   unformat_input_t *i = vam->input;
9380   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9381   u32 sw_if_index;
9382   u8 sw_if_index_set = 0;
9383   u8 v6_address_set = 0;
9384   ip6_address_t v6address;
9385   int ret;
9386
9387   /* Parse args required to build the message */
9388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9389     {
9390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9391         sw_if_index_set = 1;
9392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9393         sw_if_index_set = 1;
9394       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9395         v6_address_set = 1;
9396       else
9397         break;
9398     }
9399
9400   if (sw_if_index_set == 0)
9401     {
9402       errmsg ("missing interface name or sw_if_index");
9403       return -99;
9404     }
9405   if (!v6_address_set)
9406     {
9407       errmsg ("no address set");
9408       return -99;
9409     }
9410
9411   /* Construct the API message */
9412   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9413
9414   mp->sw_if_index = ntohl (sw_if_index);
9415   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9416
9417   /* send it... */
9418   S (mp);
9419
9420   /* Wait for a reply, return good/bad news  */
9421   W (ret);
9422   return ret;
9423 }
9424
9425 static int
9426 api_ip6nd_proxy_add_del (vat_main_t * vam)
9427 {
9428   unformat_input_t *i = vam->input;
9429   vl_api_ip6nd_proxy_add_del_t *mp;
9430   u32 sw_if_index = ~0;
9431   u8 v6_address_set = 0;
9432   ip6_address_t v6address;
9433   u8 is_del = 0;
9434   int ret;
9435
9436   /* Parse args required to build the message */
9437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9438     {
9439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9440         ;
9441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9442         ;
9443       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9444         v6_address_set = 1;
9445       if (unformat (i, "del"))
9446         is_del = 1;
9447       else
9448         {
9449           clib_warning ("parse error '%U'", format_unformat_error, i);
9450           return -99;
9451         }
9452     }
9453
9454   if (sw_if_index == ~0)
9455     {
9456       errmsg ("missing interface name or sw_if_index");
9457       return -99;
9458     }
9459   if (!v6_address_set)
9460     {
9461       errmsg ("no address set");
9462       return -99;
9463     }
9464
9465   /* Construct the API message */
9466   M (IP6ND_PROXY_ADD_DEL, mp);
9467
9468   mp->is_del = is_del;
9469   mp->sw_if_index = ntohl (sw_if_index);
9470   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9471
9472   /* send it... */
9473   S (mp);
9474
9475   /* Wait for a reply, return good/bad news  */
9476   W (ret);
9477   return ret;
9478 }
9479
9480 static int
9481 api_ip6nd_proxy_dump (vat_main_t * vam)
9482 {
9483   vl_api_ip6nd_proxy_dump_t *mp;
9484   vl_api_control_ping_t *mp_ping;
9485   int ret;
9486
9487   M (IP6ND_PROXY_DUMP, mp);
9488
9489   S (mp);
9490
9491   /* Use a control ping for synchronization */
9492   MPING (CONTROL_PING, mp_ping);
9493   S (mp_ping);
9494
9495   W (ret);
9496   return ret;
9497 }
9498
9499 static void vl_api_ip6nd_proxy_details_t_handler
9500   (vl_api_ip6nd_proxy_details_t * mp)
9501 {
9502   vat_main_t *vam = &vat_main;
9503
9504   print (vam->ofp, "host %U sw_if_index %d",
9505          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9506 }
9507
9508 static void vl_api_ip6nd_proxy_details_t_handler_json
9509   (vl_api_ip6nd_proxy_details_t * mp)
9510 {
9511   vat_main_t *vam = &vat_main;
9512   struct in6_addr ip6;
9513   vat_json_node_t *node = NULL;
9514
9515   if (VAT_JSON_ARRAY != vam->json_tree.type)
9516     {
9517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9518       vat_json_init_array (&vam->json_tree);
9519     }
9520   node = vat_json_array_add (&vam->json_tree);
9521
9522   vat_json_init_object (node);
9523   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9524
9525   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9526   vat_json_object_add_ip6 (node, "host", ip6);
9527 }
9528
9529 static int
9530 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9531 {
9532   unformat_input_t *i = vam->input;
9533   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9534   u32 sw_if_index;
9535   u8 sw_if_index_set = 0;
9536   u32 address_length = 0;
9537   u8 v6_address_set = 0;
9538   ip6_address_t v6address;
9539   u8 use_default = 0;
9540   u8 no_advertise = 0;
9541   u8 off_link = 0;
9542   u8 no_autoconfig = 0;
9543   u8 no_onlink = 0;
9544   u8 is_no = 0;
9545   u32 val_lifetime = 0;
9546   u32 pref_lifetime = 0;
9547   int ret;
9548
9549   /* Parse args required to build the message */
9550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9553         sw_if_index_set = 1;
9554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "%U/%d",
9557                          unformat_ip6_address, &v6address, &address_length))
9558         v6_address_set = 1;
9559       else if (unformat (i, "val_life %d", &val_lifetime))
9560         ;
9561       else if (unformat (i, "pref_life %d", &pref_lifetime))
9562         ;
9563       else if (unformat (i, "def"))
9564         use_default = 1;
9565       else if (unformat (i, "noadv"))
9566         no_advertise = 1;
9567       else if (unformat (i, "offl"))
9568         off_link = 1;
9569       else if (unformat (i, "noauto"))
9570         no_autoconfig = 1;
9571       else if (unformat (i, "nolink"))
9572         no_onlink = 1;
9573       else if (unformat (i, "isno"))
9574         is_no = 1;
9575       else
9576         {
9577           clib_warning ("parse error '%U'", format_unformat_error, i);
9578           return -99;
9579         }
9580     }
9581
9582   if (sw_if_index_set == 0)
9583     {
9584       errmsg ("missing interface name or sw_if_index");
9585       return -99;
9586     }
9587   if (!v6_address_set)
9588     {
9589       errmsg ("no address set");
9590       return -99;
9591     }
9592
9593   /* Construct the API message */
9594   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9595
9596   mp->sw_if_index = ntohl (sw_if_index);
9597   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9598   mp->address_length = address_length;
9599   mp->use_default = use_default;
9600   mp->no_advertise = no_advertise;
9601   mp->off_link = off_link;
9602   mp->no_autoconfig = no_autoconfig;
9603   mp->no_onlink = no_onlink;
9604   mp->is_no = is_no;
9605   mp->val_lifetime = ntohl (val_lifetime);
9606   mp->pref_lifetime = ntohl (pref_lifetime);
9607
9608   /* send it... */
9609   S (mp);
9610
9611   /* Wait for a reply, return good/bad news  */
9612   W (ret);
9613   return ret;
9614 }
9615
9616 static int
9617 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9618 {
9619   unformat_input_t *i = vam->input;
9620   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9621   u32 sw_if_index;
9622   u8 sw_if_index_set = 0;
9623   u8 suppress = 0;
9624   u8 managed = 0;
9625   u8 other = 0;
9626   u8 ll_option = 0;
9627   u8 send_unicast = 0;
9628   u8 cease = 0;
9629   u8 is_no = 0;
9630   u8 default_router = 0;
9631   u32 max_interval = 0;
9632   u32 min_interval = 0;
9633   u32 lifetime = 0;
9634   u32 initial_count = 0;
9635   u32 initial_interval = 0;
9636   int ret;
9637
9638
9639   /* Parse args required to build the message */
9640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9643         sw_if_index_set = 1;
9644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9645         sw_if_index_set = 1;
9646       else if (unformat (i, "maxint %d", &max_interval))
9647         ;
9648       else if (unformat (i, "minint %d", &min_interval))
9649         ;
9650       else if (unformat (i, "life %d", &lifetime))
9651         ;
9652       else if (unformat (i, "count %d", &initial_count))
9653         ;
9654       else if (unformat (i, "interval %d", &initial_interval))
9655         ;
9656       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9657         suppress = 1;
9658       else if (unformat (i, "managed"))
9659         managed = 1;
9660       else if (unformat (i, "other"))
9661         other = 1;
9662       else if (unformat (i, "ll"))
9663         ll_option = 1;
9664       else if (unformat (i, "send"))
9665         send_unicast = 1;
9666       else if (unformat (i, "cease"))
9667         cease = 1;
9668       else if (unformat (i, "isno"))
9669         is_no = 1;
9670       else if (unformat (i, "def"))
9671         default_router = 1;
9672       else
9673         {
9674           clib_warning ("parse error '%U'", format_unformat_error, i);
9675           return -99;
9676         }
9677     }
9678
9679   if (sw_if_index_set == 0)
9680     {
9681       errmsg ("missing interface name or sw_if_index");
9682       return -99;
9683     }
9684
9685   /* Construct the API message */
9686   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9687
9688   mp->sw_if_index = ntohl (sw_if_index);
9689   mp->max_interval = ntohl (max_interval);
9690   mp->min_interval = ntohl (min_interval);
9691   mp->lifetime = ntohl (lifetime);
9692   mp->initial_count = ntohl (initial_count);
9693   mp->initial_interval = ntohl (initial_interval);
9694   mp->suppress = suppress;
9695   mp->managed = managed;
9696   mp->other = other;
9697   mp->ll_option = ll_option;
9698   mp->send_unicast = send_unicast;
9699   mp->cease = cease;
9700   mp->is_no = is_no;
9701   mp->default_router = default_router;
9702
9703   /* send it... */
9704   S (mp);
9705
9706   /* Wait for a reply, return good/bad news  */
9707   W (ret);
9708   return ret;
9709 }
9710
9711 static int
9712 api_set_arp_neighbor_limit (vat_main_t * vam)
9713 {
9714   unformat_input_t *i = vam->input;
9715   vl_api_set_arp_neighbor_limit_t *mp;
9716   u32 arp_nbr_limit;
9717   u8 limit_set = 0;
9718   u8 is_ipv6 = 0;
9719   int ret;
9720
9721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9722     {
9723       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9724         limit_set = 1;
9725       else if (unformat (i, "ipv6"))
9726         is_ipv6 = 1;
9727       else
9728         {
9729           clib_warning ("parse error '%U'", format_unformat_error, i);
9730           return -99;
9731         }
9732     }
9733
9734   if (limit_set == 0)
9735     {
9736       errmsg ("missing limit value");
9737       return -99;
9738     }
9739
9740   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9741
9742   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9743   mp->is_ipv6 = is_ipv6;
9744
9745   S (mp);
9746   W (ret);
9747   return ret;
9748 }
9749
9750 static int
9751 api_l2_patch_add_del (vat_main_t * vam)
9752 {
9753   unformat_input_t *i = vam->input;
9754   vl_api_l2_patch_add_del_t *mp;
9755   u32 rx_sw_if_index;
9756   u8 rx_sw_if_index_set = 0;
9757   u32 tx_sw_if_index;
9758   u8 tx_sw_if_index_set = 0;
9759   u8 is_add = 1;
9760   int ret;
9761
9762   /* Parse args required to build the message */
9763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9764     {
9765       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9766         rx_sw_if_index_set = 1;
9767       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9768         tx_sw_if_index_set = 1;
9769       else if (unformat (i, "rx"))
9770         {
9771           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9772             {
9773               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9774                             &rx_sw_if_index))
9775                 rx_sw_if_index_set = 1;
9776             }
9777           else
9778             break;
9779         }
9780       else if (unformat (i, "tx"))
9781         {
9782           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9783             {
9784               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9785                             &tx_sw_if_index))
9786                 tx_sw_if_index_set = 1;
9787             }
9788           else
9789             break;
9790         }
9791       else if (unformat (i, "del"))
9792         is_add = 0;
9793       else
9794         break;
9795     }
9796
9797   if (rx_sw_if_index_set == 0)
9798     {
9799       errmsg ("missing rx interface name or rx_sw_if_index");
9800       return -99;
9801     }
9802
9803   if (tx_sw_if_index_set == 0)
9804     {
9805       errmsg ("missing tx interface name or tx_sw_if_index");
9806       return -99;
9807     }
9808
9809   M (L2_PATCH_ADD_DEL, mp);
9810
9811   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9812   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9813   mp->is_add = is_add;
9814
9815   S (mp);
9816   W (ret);
9817   return ret;
9818 }
9819
9820 u8 is_del;
9821 u8 localsid_addr[16];
9822 u8 end_psp;
9823 u8 behavior;
9824 u32 sw_if_index;
9825 u32 vlan_index;
9826 u32 fib_table;
9827 u8 nh_addr[16];
9828
9829 static int
9830 api_sr_localsid_add_del (vat_main_t * vam)
9831 {
9832   unformat_input_t *i = vam->input;
9833   vl_api_sr_localsid_add_del_t *mp;
9834
9835   u8 is_del;
9836   ip6_address_t localsid;
9837   u8 end_psp = 0;
9838   u8 behavior = ~0;
9839   u32 sw_if_index;
9840   u32 fib_table = ~(u32) 0;
9841   ip6_address_t next_hop;
9842
9843   bool nexthop_set = 0;
9844
9845   int ret;
9846
9847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9848     {
9849       if (unformat (i, "del"))
9850         is_del = 1;
9851       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9852       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9853         nexthop_set = 1;
9854       else if (unformat (i, "behavior %u", &behavior));
9855       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9856       else if (unformat (i, "fib-table %u", &fib_table));
9857       else if (unformat (i, "end.psp %u", &behavior));
9858       else
9859         break;
9860     }
9861
9862   M (SR_LOCALSID_ADD_DEL, mp);
9863
9864   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9865   if (nexthop_set)
9866     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9867   mp->behavior = behavior;
9868   mp->sw_if_index = ntohl (sw_if_index);
9869   mp->fib_table = ntohl (fib_table);
9870   mp->end_psp = end_psp;
9871   mp->is_del = is_del;
9872
9873   S (mp);
9874   W (ret);
9875   return ret;
9876 }
9877
9878 static int
9879 api_ioam_enable (vat_main_t * vam)
9880 {
9881   unformat_input_t *input = vam->input;
9882   vl_api_ioam_enable_t *mp;
9883   u32 id = 0;
9884   int has_trace_option = 0;
9885   int has_pot_option = 0;
9886   int has_seqno_option = 0;
9887   int has_analyse_option = 0;
9888   int ret;
9889
9890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9891     {
9892       if (unformat (input, "trace"))
9893         has_trace_option = 1;
9894       else if (unformat (input, "pot"))
9895         has_pot_option = 1;
9896       else if (unformat (input, "seqno"))
9897         has_seqno_option = 1;
9898       else if (unformat (input, "analyse"))
9899         has_analyse_option = 1;
9900       else
9901         break;
9902     }
9903   M (IOAM_ENABLE, mp);
9904   mp->id = htons (id);
9905   mp->seqno = has_seqno_option;
9906   mp->analyse = has_analyse_option;
9907   mp->pot_enable = has_pot_option;
9908   mp->trace_enable = has_trace_option;
9909
9910   S (mp);
9911   W (ret);
9912   return ret;
9913 }
9914
9915
9916 static int
9917 api_ioam_disable (vat_main_t * vam)
9918 {
9919   vl_api_ioam_disable_t *mp;
9920   int ret;
9921
9922   M (IOAM_DISABLE, mp);
9923   S (mp);
9924   W (ret);
9925   return ret;
9926 }
9927
9928 #define foreach_tcp_proto_field                 \
9929 _(src_port)                                     \
9930 _(dst_port)
9931
9932 #define foreach_udp_proto_field                 \
9933 _(src_port)                                     \
9934 _(dst_port)
9935
9936 #define foreach_ip4_proto_field                 \
9937 _(src_address)                                  \
9938 _(dst_address)                                  \
9939 _(tos)                                          \
9940 _(length)                                       \
9941 _(fragment_id)                                  \
9942 _(ttl)                                          \
9943 _(protocol)                                     \
9944 _(checksum)
9945
9946 typedef struct
9947 {
9948   u16 src_port, dst_port;
9949 } tcpudp_header_t;
9950
9951 #if VPP_API_TEST_BUILTIN == 0
9952 uword
9953 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9954 {
9955   u8 **maskp = va_arg (*args, u8 **);
9956   u8 *mask = 0;
9957   u8 found_something = 0;
9958   tcp_header_t *tcp;
9959
9960 #define _(a) u8 a=0;
9961   foreach_tcp_proto_field;
9962 #undef _
9963
9964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9965     {
9966       if (0);
9967 #define _(a) else if (unformat (input, #a)) a=1;
9968       foreach_tcp_proto_field
9969 #undef _
9970         else
9971         break;
9972     }
9973
9974 #define _(a) found_something += a;
9975   foreach_tcp_proto_field;
9976 #undef _
9977
9978   if (found_something == 0)
9979     return 0;
9980
9981   vec_validate (mask, sizeof (*tcp) - 1);
9982
9983   tcp = (tcp_header_t *) mask;
9984
9985 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9986   foreach_tcp_proto_field;
9987 #undef _
9988
9989   *maskp = mask;
9990   return 1;
9991 }
9992
9993 uword
9994 unformat_udp_mask (unformat_input_t * input, va_list * args)
9995 {
9996   u8 **maskp = va_arg (*args, u8 **);
9997   u8 *mask = 0;
9998   u8 found_something = 0;
9999   udp_header_t *udp;
10000
10001 #define _(a) u8 a=0;
10002   foreach_udp_proto_field;
10003 #undef _
10004
10005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10006     {
10007       if (0);
10008 #define _(a) else if (unformat (input, #a)) a=1;
10009       foreach_udp_proto_field
10010 #undef _
10011         else
10012         break;
10013     }
10014
10015 #define _(a) found_something += a;
10016   foreach_udp_proto_field;
10017 #undef _
10018
10019   if (found_something == 0)
10020     return 0;
10021
10022   vec_validate (mask, sizeof (*udp) - 1);
10023
10024   udp = (udp_header_t *) mask;
10025
10026 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10027   foreach_udp_proto_field;
10028 #undef _
10029
10030   *maskp = mask;
10031   return 1;
10032 }
10033
10034 uword
10035 unformat_l4_mask (unformat_input_t * input, va_list * args)
10036 {
10037   u8 **maskp = va_arg (*args, u8 **);
10038   u16 src_port = 0, dst_port = 0;
10039   tcpudp_header_t *tcpudp;
10040
10041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10042     {
10043       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10044         return 1;
10045       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10046         return 1;
10047       else if (unformat (input, "src_port"))
10048         src_port = 0xFFFF;
10049       else if (unformat (input, "dst_port"))
10050         dst_port = 0xFFFF;
10051       else
10052         return 0;
10053     }
10054
10055   if (!src_port && !dst_port)
10056     return 0;
10057
10058   u8 *mask = 0;
10059   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10060
10061   tcpudp = (tcpudp_header_t *) mask;
10062   tcpudp->src_port = src_port;
10063   tcpudp->dst_port = dst_port;
10064
10065   *maskp = mask;
10066
10067   return 1;
10068 }
10069
10070 uword
10071 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10072 {
10073   u8 **maskp = va_arg (*args, u8 **);
10074   u8 *mask = 0;
10075   u8 found_something = 0;
10076   ip4_header_t *ip;
10077
10078 #define _(a) u8 a=0;
10079   foreach_ip4_proto_field;
10080 #undef _
10081   u8 version = 0;
10082   u8 hdr_length = 0;
10083
10084
10085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10086     {
10087       if (unformat (input, "version"))
10088         version = 1;
10089       else if (unformat (input, "hdr_length"))
10090         hdr_length = 1;
10091       else if (unformat (input, "src"))
10092         src_address = 1;
10093       else if (unformat (input, "dst"))
10094         dst_address = 1;
10095       else if (unformat (input, "proto"))
10096         protocol = 1;
10097
10098 #define _(a) else if (unformat (input, #a)) a=1;
10099       foreach_ip4_proto_field
10100 #undef _
10101         else
10102         break;
10103     }
10104
10105 #define _(a) found_something += a;
10106   foreach_ip4_proto_field;
10107 #undef _
10108
10109   if (found_something == 0)
10110     return 0;
10111
10112   vec_validate (mask, sizeof (*ip) - 1);
10113
10114   ip = (ip4_header_t *) mask;
10115
10116 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10117   foreach_ip4_proto_field;
10118 #undef _
10119
10120   ip->ip_version_and_header_length = 0;
10121
10122   if (version)
10123     ip->ip_version_and_header_length |= 0xF0;
10124
10125   if (hdr_length)
10126     ip->ip_version_and_header_length |= 0x0F;
10127
10128   *maskp = mask;
10129   return 1;
10130 }
10131
10132 #define foreach_ip6_proto_field                 \
10133 _(src_address)                                  \
10134 _(dst_address)                                  \
10135 _(payload_length)                               \
10136 _(hop_limit)                                    \
10137 _(protocol)
10138
10139 uword
10140 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10141 {
10142   u8 **maskp = va_arg (*args, u8 **);
10143   u8 *mask = 0;
10144   u8 found_something = 0;
10145   ip6_header_t *ip;
10146   u32 ip_version_traffic_class_and_flow_label;
10147
10148 #define _(a) u8 a=0;
10149   foreach_ip6_proto_field;
10150 #undef _
10151   u8 version = 0;
10152   u8 traffic_class = 0;
10153   u8 flow_label = 0;
10154
10155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (input, "version"))
10158         version = 1;
10159       else if (unformat (input, "traffic-class"))
10160         traffic_class = 1;
10161       else if (unformat (input, "flow-label"))
10162         flow_label = 1;
10163       else if (unformat (input, "src"))
10164         src_address = 1;
10165       else if (unformat (input, "dst"))
10166         dst_address = 1;
10167       else if (unformat (input, "proto"))
10168         protocol = 1;
10169
10170 #define _(a) else if (unformat (input, #a)) a=1;
10171       foreach_ip6_proto_field
10172 #undef _
10173         else
10174         break;
10175     }
10176
10177 #define _(a) found_something += a;
10178   foreach_ip6_proto_field;
10179 #undef _
10180
10181   if (found_something == 0)
10182     return 0;
10183
10184   vec_validate (mask, sizeof (*ip) - 1);
10185
10186   ip = (ip6_header_t *) mask;
10187
10188 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10189   foreach_ip6_proto_field;
10190 #undef _
10191
10192   ip_version_traffic_class_and_flow_label = 0;
10193
10194   if (version)
10195     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10196
10197   if (traffic_class)
10198     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10199
10200   if (flow_label)
10201     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10202
10203   ip->ip_version_traffic_class_and_flow_label =
10204     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10205
10206   *maskp = mask;
10207   return 1;
10208 }
10209
10210 uword
10211 unformat_l3_mask (unformat_input_t * input, va_list * args)
10212 {
10213   u8 **maskp = va_arg (*args, u8 **);
10214
10215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10218         return 1;
10219       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10220         return 1;
10221       else
10222         break;
10223     }
10224   return 0;
10225 }
10226
10227 uword
10228 unformat_l2_mask (unformat_input_t * input, va_list * args)
10229 {
10230   u8 **maskp = va_arg (*args, u8 **);
10231   u8 *mask = 0;
10232   u8 src = 0;
10233   u8 dst = 0;
10234   u8 proto = 0;
10235   u8 tag1 = 0;
10236   u8 tag2 = 0;
10237   u8 ignore_tag1 = 0;
10238   u8 ignore_tag2 = 0;
10239   u8 cos1 = 0;
10240   u8 cos2 = 0;
10241   u8 dot1q = 0;
10242   u8 dot1ad = 0;
10243   int len = 14;
10244
10245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (input, "src"))
10248         src = 1;
10249       else if (unformat (input, "dst"))
10250         dst = 1;
10251       else if (unformat (input, "proto"))
10252         proto = 1;
10253       else if (unformat (input, "tag1"))
10254         tag1 = 1;
10255       else if (unformat (input, "tag2"))
10256         tag2 = 1;
10257       else if (unformat (input, "ignore-tag1"))
10258         ignore_tag1 = 1;
10259       else if (unformat (input, "ignore-tag2"))
10260         ignore_tag2 = 1;
10261       else if (unformat (input, "cos1"))
10262         cos1 = 1;
10263       else if (unformat (input, "cos2"))
10264         cos2 = 1;
10265       else if (unformat (input, "dot1q"))
10266         dot1q = 1;
10267       else if (unformat (input, "dot1ad"))
10268         dot1ad = 1;
10269       else
10270         break;
10271     }
10272   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10273        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10274     return 0;
10275
10276   if (tag1 || ignore_tag1 || cos1 || dot1q)
10277     len = 18;
10278   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10279     len = 22;
10280
10281   vec_validate (mask, len - 1);
10282
10283   if (dst)
10284     memset (mask, 0xff, 6);
10285
10286   if (src)
10287     memset (mask + 6, 0xff, 6);
10288
10289   if (tag2 || dot1ad)
10290     {
10291       /* inner vlan tag */
10292       if (tag2)
10293         {
10294           mask[19] = 0xff;
10295           mask[18] = 0x0f;
10296         }
10297       if (cos2)
10298         mask[18] |= 0xe0;
10299       if (proto)
10300         mask[21] = mask[20] = 0xff;
10301       if (tag1)
10302         {
10303           mask[15] = 0xff;
10304           mask[14] = 0x0f;
10305         }
10306       if (cos1)
10307         mask[14] |= 0xe0;
10308       *maskp = mask;
10309       return 1;
10310     }
10311   if (tag1 | dot1q)
10312     {
10313       if (tag1)
10314         {
10315           mask[15] = 0xff;
10316           mask[14] = 0x0f;
10317         }
10318       if (cos1)
10319         mask[14] |= 0xe0;
10320       if (proto)
10321         mask[16] = mask[17] = 0xff;
10322
10323       *maskp = mask;
10324       return 1;
10325     }
10326   if (cos2)
10327     mask[18] |= 0xe0;
10328   if (cos1)
10329     mask[14] |= 0xe0;
10330   if (proto)
10331     mask[12] = mask[13] = 0xff;
10332
10333   *maskp = mask;
10334   return 1;
10335 }
10336
10337 uword
10338 unformat_classify_mask (unformat_input_t * input, va_list * args)
10339 {
10340   u8 **maskp = va_arg (*args, u8 **);
10341   u32 *skipp = va_arg (*args, u32 *);
10342   u32 *matchp = va_arg (*args, u32 *);
10343   u32 match;
10344   u8 *mask = 0;
10345   u8 *l2 = 0;
10346   u8 *l3 = 0;
10347   u8 *l4 = 0;
10348   int i;
10349
10350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10351     {
10352       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10353         ;
10354       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10355         ;
10356       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10357         ;
10358       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10359         ;
10360       else
10361         break;
10362     }
10363
10364   if (l4 && !l3)
10365     {
10366       vec_free (mask);
10367       vec_free (l2);
10368       vec_free (l4);
10369       return 0;
10370     }
10371
10372   if (mask || l2 || l3 || l4)
10373     {
10374       if (l2 || l3 || l4)
10375         {
10376           /* "With a free Ethernet header in every package" */
10377           if (l2 == 0)
10378             vec_validate (l2, 13);
10379           mask = l2;
10380           if (vec_len (l3))
10381             {
10382               vec_append (mask, l3);
10383               vec_free (l3);
10384             }
10385           if (vec_len (l4))
10386             {
10387               vec_append (mask, l4);
10388               vec_free (l4);
10389             }
10390         }
10391
10392       /* Scan forward looking for the first significant mask octet */
10393       for (i = 0; i < vec_len (mask); i++)
10394         if (mask[i])
10395           break;
10396
10397       /* compute (skip, match) params */
10398       *skipp = i / sizeof (u32x4);
10399       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10400
10401       /* Pad mask to an even multiple of the vector size */
10402       while (vec_len (mask) % sizeof (u32x4))
10403         vec_add1 (mask, 0);
10404
10405       match = vec_len (mask) / sizeof (u32x4);
10406
10407       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10408         {
10409           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10410           if (*tmp || *(tmp + 1))
10411             break;
10412           match--;
10413         }
10414       if (match == 0)
10415         clib_warning ("BUG: match 0");
10416
10417       _vec_len (mask) = match * sizeof (u32x4);
10418
10419       *matchp = match;
10420       *maskp = mask;
10421
10422       return 1;
10423     }
10424
10425   return 0;
10426 }
10427 #endif /* VPP_API_TEST_BUILTIN */
10428
10429 #define foreach_l2_next                         \
10430 _(drop, DROP)                                   \
10431 _(ethernet, ETHERNET_INPUT)                     \
10432 _(ip4, IP4_INPUT)                               \
10433 _(ip6, IP6_INPUT)
10434
10435 uword
10436 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10437 {
10438   u32 *miss_next_indexp = va_arg (*args, u32 *);
10439   u32 next_index = 0;
10440   u32 tmp;
10441
10442 #define _(n,N) \
10443   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10444   foreach_l2_next;
10445 #undef _
10446
10447   if (unformat (input, "%d", &tmp))
10448     {
10449       next_index = tmp;
10450       goto out;
10451     }
10452
10453   return 0;
10454
10455 out:
10456   *miss_next_indexp = next_index;
10457   return 1;
10458 }
10459
10460 #define foreach_ip_next                         \
10461 _(drop, DROP)                                   \
10462 _(local, LOCAL)                                 \
10463 _(rewrite, REWRITE)
10464
10465 uword
10466 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10467 {
10468   u32 *miss_next_indexp = va_arg (*args, u32 *);
10469   u32 next_index = 0;
10470   u32 tmp;
10471
10472 #define _(n,N) \
10473   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10474   foreach_ip_next;
10475 #undef _
10476
10477   if (unformat (input, "%d", &tmp))
10478     {
10479       next_index = tmp;
10480       goto out;
10481     }
10482
10483   return 0;
10484
10485 out:
10486   *miss_next_indexp = next_index;
10487   return 1;
10488 }
10489
10490 #define foreach_acl_next                        \
10491 _(deny, DENY)
10492
10493 uword
10494 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10495 {
10496   u32 *miss_next_indexp = va_arg (*args, u32 *);
10497   u32 next_index = 0;
10498   u32 tmp;
10499
10500 #define _(n,N) \
10501   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10502   foreach_acl_next;
10503 #undef _
10504
10505   if (unformat (input, "permit"))
10506     {
10507       next_index = ~0;
10508       goto out;
10509     }
10510   else if (unformat (input, "%d", &tmp))
10511     {
10512       next_index = tmp;
10513       goto out;
10514     }
10515
10516   return 0;
10517
10518 out:
10519   *miss_next_indexp = next_index;
10520   return 1;
10521 }
10522
10523 uword
10524 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10525 {
10526   u32 *r = va_arg (*args, u32 *);
10527
10528   if (unformat (input, "conform-color"))
10529     *r = POLICE_CONFORM;
10530   else if (unformat (input, "exceed-color"))
10531     *r = POLICE_EXCEED;
10532   else
10533     return 0;
10534
10535   return 1;
10536 }
10537
10538 static int
10539 api_classify_add_del_table (vat_main_t * vam)
10540 {
10541   unformat_input_t *i = vam->input;
10542   vl_api_classify_add_del_table_t *mp;
10543
10544   u32 nbuckets = 2;
10545   u32 skip = ~0;
10546   u32 match = ~0;
10547   int is_add = 1;
10548   int del_chain = 0;
10549   u32 table_index = ~0;
10550   u32 next_table_index = ~0;
10551   u32 miss_next_index = ~0;
10552   u32 memory_size = 32 << 20;
10553   u8 *mask = 0;
10554   u32 current_data_flag = 0;
10555   int current_data_offset = 0;
10556   int ret;
10557
10558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (unformat (i, "del"))
10561         is_add = 0;
10562       else if (unformat (i, "del-chain"))
10563         {
10564           is_add = 0;
10565           del_chain = 1;
10566         }
10567       else if (unformat (i, "buckets %d", &nbuckets))
10568         ;
10569       else if (unformat (i, "memory_size %d", &memory_size))
10570         ;
10571       else if (unformat (i, "skip %d", &skip))
10572         ;
10573       else if (unformat (i, "match %d", &match))
10574         ;
10575       else if (unformat (i, "table %d", &table_index))
10576         ;
10577       else if (unformat (i, "mask %U", unformat_classify_mask,
10578                          &mask, &skip, &match))
10579         ;
10580       else if (unformat (i, "next-table %d", &next_table_index))
10581         ;
10582       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10583                          &miss_next_index))
10584         ;
10585       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10586                          &miss_next_index))
10587         ;
10588       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10589                          &miss_next_index))
10590         ;
10591       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10592         ;
10593       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10594         ;
10595       else
10596         break;
10597     }
10598
10599   if (is_add && mask == 0)
10600     {
10601       errmsg ("Mask required");
10602       return -99;
10603     }
10604
10605   if (is_add && skip == ~0)
10606     {
10607       errmsg ("skip count required");
10608       return -99;
10609     }
10610
10611   if (is_add && match == ~0)
10612     {
10613       errmsg ("match count required");
10614       return -99;
10615     }
10616
10617   if (!is_add && table_index == ~0)
10618     {
10619       errmsg ("table index required for delete");
10620       return -99;
10621     }
10622
10623   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10624
10625   mp->is_add = is_add;
10626   mp->del_chain = del_chain;
10627   mp->table_index = ntohl (table_index);
10628   mp->nbuckets = ntohl (nbuckets);
10629   mp->memory_size = ntohl (memory_size);
10630   mp->skip_n_vectors = ntohl (skip);
10631   mp->match_n_vectors = ntohl (match);
10632   mp->next_table_index = ntohl (next_table_index);
10633   mp->miss_next_index = ntohl (miss_next_index);
10634   mp->current_data_flag = ntohl (current_data_flag);
10635   mp->current_data_offset = ntohl (current_data_offset);
10636   clib_memcpy (mp->mask, mask, vec_len (mask));
10637
10638   vec_free (mask);
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 #if VPP_API_TEST_BUILTIN == 0
10646 uword
10647 unformat_l4_match (unformat_input_t * input, va_list * args)
10648 {
10649   u8 **matchp = va_arg (*args, u8 **);
10650
10651   u8 *proto_header = 0;
10652   int src_port = 0;
10653   int dst_port = 0;
10654
10655   tcpudp_header_t h;
10656
10657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10658     {
10659       if (unformat (input, "src_port %d", &src_port))
10660         ;
10661       else if (unformat (input, "dst_port %d", &dst_port))
10662         ;
10663       else
10664         return 0;
10665     }
10666
10667   h.src_port = clib_host_to_net_u16 (src_port);
10668   h.dst_port = clib_host_to_net_u16 (dst_port);
10669   vec_validate (proto_header, sizeof (h) - 1);
10670   memcpy (proto_header, &h, sizeof (h));
10671
10672   *matchp = proto_header;
10673
10674   return 1;
10675 }
10676
10677 uword
10678 unformat_ip4_match (unformat_input_t * input, va_list * args)
10679 {
10680   u8 **matchp = va_arg (*args, u8 **);
10681   u8 *match = 0;
10682   ip4_header_t *ip;
10683   int version = 0;
10684   u32 version_val;
10685   int hdr_length = 0;
10686   u32 hdr_length_val;
10687   int src = 0, dst = 0;
10688   ip4_address_t src_val, dst_val;
10689   int proto = 0;
10690   u32 proto_val;
10691   int tos = 0;
10692   u32 tos_val;
10693   int length = 0;
10694   u32 length_val;
10695   int fragment_id = 0;
10696   u32 fragment_id_val;
10697   int ttl = 0;
10698   int ttl_val;
10699   int checksum = 0;
10700   u32 checksum_val;
10701
10702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (input, "version %d", &version_val))
10705         version = 1;
10706       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10707         hdr_length = 1;
10708       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10709         src = 1;
10710       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10711         dst = 1;
10712       else if (unformat (input, "proto %d", &proto_val))
10713         proto = 1;
10714       else if (unformat (input, "tos %d", &tos_val))
10715         tos = 1;
10716       else if (unformat (input, "length %d", &length_val))
10717         length = 1;
10718       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10719         fragment_id = 1;
10720       else if (unformat (input, "ttl %d", &ttl_val))
10721         ttl = 1;
10722       else if (unformat (input, "checksum %d", &checksum_val))
10723         checksum = 1;
10724       else
10725         break;
10726     }
10727
10728   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10729       + ttl + checksum == 0)
10730     return 0;
10731
10732   /*
10733    * Aligned because we use the real comparison functions
10734    */
10735   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10736
10737   ip = (ip4_header_t *) match;
10738
10739   /* These are realistically matched in practice */
10740   if (src)
10741     ip->src_address.as_u32 = src_val.as_u32;
10742
10743   if (dst)
10744     ip->dst_address.as_u32 = dst_val.as_u32;
10745
10746   if (proto)
10747     ip->protocol = proto_val;
10748
10749
10750   /* These are not, but they're included for completeness */
10751   if (version)
10752     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10753
10754   if (hdr_length)
10755     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10756
10757   if (tos)
10758     ip->tos = tos_val;
10759
10760   if (length)
10761     ip->length = clib_host_to_net_u16 (length_val);
10762
10763   if (ttl)
10764     ip->ttl = ttl_val;
10765
10766   if (checksum)
10767     ip->checksum = clib_host_to_net_u16 (checksum_val);
10768
10769   *matchp = match;
10770   return 1;
10771 }
10772
10773 uword
10774 unformat_ip6_match (unformat_input_t * input, va_list * args)
10775 {
10776   u8 **matchp = va_arg (*args, u8 **);
10777   u8 *match = 0;
10778   ip6_header_t *ip;
10779   int version = 0;
10780   u32 version_val;
10781   u8 traffic_class = 0;
10782   u32 traffic_class_val = 0;
10783   u8 flow_label = 0;
10784   u8 flow_label_val;
10785   int src = 0, dst = 0;
10786   ip6_address_t src_val, dst_val;
10787   int proto = 0;
10788   u32 proto_val;
10789   int payload_length = 0;
10790   u32 payload_length_val;
10791   int hop_limit = 0;
10792   int hop_limit_val;
10793   u32 ip_version_traffic_class_and_flow_label;
10794
10795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10796     {
10797       if (unformat (input, "version %d", &version_val))
10798         version = 1;
10799       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10800         traffic_class = 1;
10801       else if (unformat (input, "flow_label %d", &flow_label_val))
10802         flow_label = 1;
10803       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10804         src = 1;
10805       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10806         dst = 1;
10807       else if (unformat (input, "proto %d", &proto_val))
10808         proto = 1;
10809       else if (unformat (input, "payload_length %d", &payload_length_val))
10810         payload_length = 1;
10811       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10812         hop_limit = 1;
10813       else
10814         break;
10815     }
10816
10817   if (version + traffic_class + flow_label + src + dst + proto +
10818       payload_length + hop_limit == 0)
10819     return 0;
10820
10821   /*
10822    * Aligned because we use the real comparison functions
10823    */
10824   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10825
10826   ip = (ip6_header_t *) match;
10827
10828   if (src)
10829     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10830
10831   if (dst)
10832     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10833
10834   if (proto)
10835     ip->protocol = proto_val;
10836
10837   ip_version_traffic_class_and_flow_label = 0;
10838
10839   if (version)
10840     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10841
10842   if (traffic_class)
10843     ip_version_traffic_class_and_flow_label |=
10844       (traffic_class_val & 0xFF) << 20;
10845
10846   if (flow_label)
10847     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10848
10849   ip->ip_version_traffic_class_and_flow_label =
10850     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10851
10852   if (payload_length)
10853     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10854
10855   if (hop_limit)
10856     ip->hop_limit = hop_limit_val;
10857
10858   *matchp = match;
10859   return 1;
10860 }
10861
10862 uword
10863 unformat_l3_match (unformat_input_t * input, va_list * args)
10864 {
10865   u8 **matchp = va_arg (*args, u8 **);
10866
10867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10870         return 1;
10871       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10872         return 1;
10873       else
10874         break;
10875     }
10876   return 0;
10877 }
10878
10879 uword
10880 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10881 {
10882   u8 *tagp = va_arg (*args, u8 *);
10883   u32 tag;
10884
10885   if (unformat (input, "%d", &tag))
10886     {
10887       tagp[0] = (tag >> 8) & 0x0F;
10888       tagp[1] = tag & 0xFF;
10889       return 1;
10890     }
10891
10892   return 0;
10893 }
10894
10895 uword
10896 unformat_l2_match (unformat_input_t * input, va_list * args)
10897 {
10898   u8 **matchp = va_arg (*args, u8 **);
10899   u8 *match = 0;
10900   u8 src = 0;
10901   u8 src_val[6];
10902   u8 dst = 0;
10903   u8 dst_val[6];
10904   u8 proto = 0;
10905   u16 proto_val;
10906   u8 tag1 = 0;
10907   u8 tag1_val[2];
10908   u8 tag2 = 0;
10909   u8 tag2_val[2];
10910   int len = 14;
10911   u8 ignore_tag1 = 0;
10912   u8 ignore_tag2 = 0;
10913   u8 cos1 = 0;
10914   u8 cos2 = 0;
10915   u32 cos1_val = 0;
10916   u32 cos2_val = 0;
10917
10918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10921         src = 1;
10922       else
10923         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10924         dst = 1;
10925       else if (unformat (input, "proto %U",
10926                          unformat_ethernet_type_host_byte_order, &proto_val))
10927         proto = 1;
10928       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10929         tag1 = 1;
10930       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10931         tag2 = 1;
10932       else if (unformat (input, "ignore-tag1"))
10933         ignore_tag1 = 1;
10934       else if (unformat (input, "ignore-tag2"))
10935         ignore_tag2 = 1;
10936       else if (unformat (input, "cos1 %d", &cos1_val))
10937         cos1 = 1;
10938       else if (unformat (input, "cos2 %d", &cos2_val))
10939         cos2 = 1;
10940       else
10941         break;
10942     }
10943   if ((src + dst + proto + tag1 + tag2 +
10944        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10945     return 0;
10946
10947   if (tag1 || ignore_tag1 || cos1)
10948     len = 18;
10949   if (tag2 || ignore_tag2 || cos2)
10950     len = 22;
10951
10952   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10953
10954   if (dst)
10955     clib_memcpy (match, dst_val, 6);
10956
10957   if (src)
10958     clib_memcpy (match + 6, src_val, 6);
10959
10960   if (tag2)
10961     {
10962       /* inner vlan tag */
10963       match[19] = tag2_val[1];
10964       match[18] = tag2_val[0];
10965       if (cos2)
10966         match[18] |= (cos2_val & 0x7) << 5;
10967       if (proto)
10968         {
10969           match[21] = proto_val & 0xff;
10970           match[20] = proto_val >> 8;
10971         }
10972       if (tag1)
10973         {
10974           match[15] = tag1_val[1];
10975           match[14] = tag1_val[0];
10976         }
10977       if (cos1)
10978         match[14] |= (cos1_val & 0x7) << 5;
10979       *matchp = match;
10980       return 1;
10981     }
10982   if (tag1)
10983     {
10984       match[15] = tag1_val[1];
10985       match[14] = tag1_val[0];
10986       if (proto)
10987         {
10988           match[17] = proto_val & 0xff;
10989           match[16] = proto_val >> 8;
10990         }
10991       if (cos1)
10992         match[14] |= (cos1_val & 0x7) << 5;
10993
10994       *matchp = match;
10995       return 1;
10996     }
10997   if (cos2)
10998     match[18] |= (cos2_val & 0x7) << 5;
10999   if (cos1)
11000     match[14] |= (cos1_val & 0x7) << 5;
11001   if (proto)
11002     {
11003       match[13] = proto_val & 0xff;
11004       match[12] = proto_val >> 8;
11005     }
11006
11007   *matchp = match;
11008   return 1;
11009 }
11010 #endif
11011
11012 uword
11013 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11014 {
11015   u8 **matchp = va_arg (*args, u8 **);
11016   u32 skip_n_vectors = va_arg (*args, u32);
11017   u32 match_n_vectors = va_arg (*args, u32);
11018
11019   u8 *match = 0;
11020   u8 *l2 = 0;
11021   u8 *l3 = 0;
11022   u8 *l4 = 0;
11023
11024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11025     {
11026       if (unformat (input, "hex %U", unformat_hex_string, &match))
11027         ;
11028       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11029         ;
11030       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11031         ;
11032       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11033         ;
11034       else
11035         break;
11036     }
11037
11038   if (l4 && !l3)
11039     {
11040       vec_free (match);
11041       vec_free (l2);
11042       vec_free (l4);
11043       return 0;
11044     }
11045
11046   if (match || l2 || l3 || l4)
11047     {
11048       if (l2 || l3 || l4)
11049         {
11050           /* "Win a free Ethernet header in every packet" */
11051           if (l2 == 0)
11052             vec_validate_aligned (l2, 13, sizeof (u32x4));
11053           match = l2;
11054           if (vec_len (l3))
11055             {
11056               vec_append_aligned (match, l3, sizeof (u32x4));
11057               vec_free (l3);
11058             }
11059           if (vec_len (l4))
11060             {
11061               vec_append_aligned (match, l4, sizeof (u32x4));
11062               vec_free (l4);
11063             }
11064         }
11065
11066       /* Make sure the vector is big enough even if key is all 0's */
11067       vec_validate_aligned
11068         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11069          sizeof (u32x4));
11070
11071       /* Set size, include skipped vectors */
11072       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11073
11074       *matchp = match;
11075
11076       return 1;
11077     }
11078
11079   return 0;
11080 }
11081
11082 static int
11083 api_classify_add_del_session (vat_main_t * vam)
11084 {
11085   unformat_input_t *i = vam->input;
11086   vl_api_classify_add_del_session_t *mp;
11087   int is_add = 1;
11088   u32 table_index = ~0;
11089   u32 hit_next_index = ~0;
11090   u32 opaque_index = ~0;
11091   u8 *match = 0;
11092   i32 advance = 0;
11093   u32 skip_n_vectors = 0;
11094   u32 match_n_vectors = 0;
11095   u32 action = 0;
11096   u32 metadata = 0;
11097   int ret;
11098
11099   /*
11100    * Warning: you have to supply skip_n and match_n
11101    * because the API client cant simply look at the classify
11102    * table object.
11103    */
11104
11105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11106     {
11107       if (unformat (i, "del"))
11108         is_add = 0;
11109       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11110                          &hit_next_index))
11111         ;
11112       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11113                          &hit_next_index))
11114         ;
11115       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11116                          &hit_next_index))
11117         ;
11118       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11119         ;
11120       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11121         ;
11122       else if (unformat (i, "opaque-index %d", &opaque_index))
11123         ;
11124       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11125         ;
11126       else if (unformat (i, "match_n %d", &match_n_vectors))
11127         ;
11128       else if (unformat (i, "match %U", api_unformat_classify_match,
11129                          &match, skip_n_vectors, match_n_vectors))
11130         ;
11131       else if (unformat (i, "advance %d", &advance))
11132         ;
11133       else if (unformat (i, "table-index %d", &table_index))
11134         ;
11135       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11136         action = 1;
11137       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11138         action = 2;
11139       else if (unformat (i, "action %d", &action))
11140         ;
11141       else if (unformat (i, "metadata %d", &metadata))
11142         ;
11143       else
11144         break;
11145     }
11146
11147   if (table_index == ~0)
11148     {
11149       errmsg ("Table index required");
11150       return -99;
11151     }
11152
11153   if (is_add && match == 0)
11154     {
11155       errmsg ("Match value required");
11156       return -99;
11157     }
11158
11159   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11160
11161   mp->is_add = is_add;
11162   mp->table_index = ntohl (table_index);
11163   mp->hit_next_index = ntohl (hit_next_index);
11164   mp->opaque_index = ntohl (opaque_index);
11165   mp->advance = ntohl (advance);
11166   mp->action = action;
11167   mp->metadata = ntohl (metadata);
11168   clib_memcpy (mp->match, match, vec_len (match));
11169   vec_free (match);
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static int
11177 api_classify_set_interface_ip_table (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_classify_set_interface_ip_table_t *mp;
11181   u32 sw_if_index;
11182   int sw_if_index_set;
11183   u32 table_index = ~0;
11184   u8 is_ipv6 = 0;
11185   int ret;
11186
11187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11188     {
11189       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11190         sw_if_index_set = 1;
11191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "table %d", &table_index))
11194         ;
11195       else
11196         {
11197           clib_warning ("parse error '%U'", format_unformat_error, i);
11198           return -99;
11199         }
11200     }
11201
11202   if (sw_if_index_set == 0)
11203     {
11204       errmsg ("missing interface name or sw_if_index");
11205       return -99;
11206     }
11207
11208
11209   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11210
11211   mp->sw_if_index = ntohl (sw_if_index);
11212   mp->table_index = ntohl (table_index);
11213   mp->is_ipv6 = is_ipv6;
11214
11215   S (mp);
11216   W (ret);
11217   return ret;
11218 }
11219
11220 static int
11221 api_classify_set_interface_l2_tables (vat_main_t * vam)
11222 {
11223   unformat_input_t *i = vam->input;
11224   vl_api_classify_set_interface_l2_tables_t *mp;
11225   u32 sw_if_index;
11226   int sw_if_index_set;
11227   u32 ip4_table_index = ~0;
11228   u32 ip6_table_index = ~0;
11229   u32 other_table_index = ~0;
11230   u32 is_input = 1;
11231   int ret;
11232
11233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11234     {
11235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11236         sw_if_index_set = 1;
11237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11238         sw_if_index_set = 1;
11239       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11240         ;
11241       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11242         ;
11243       else if (unformat (i, "other-table %d", &other_table_index))
11244         ;
11245       else if (unformat (i, "is-input %d", &is_input))
11246         ;
11247       else
11248         {
11249           clib_warning ("parse error '%U'", format_unformat_error, i);
11250           return -99;
11251         }
11252     }
11253
11254   if (sw_if_index_set == 0)
11255     {
11256       errmsg ("missing interface name or sw_if_index");
11257       return -99;
11258     }
11259
11260
11261   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11262
11263   mp->sw_if_index = ntohl (sw_if_index);
11264   mp->ip4_table_index = ntohl (ip4_table_index);
11265   mp->ip6_table_index = ntohl (ip6_table_index);
11266   mp->other_table_index = ntohl (other_table_index);
11267   mp->is_input = (u8) is_input;
11268
11269   S (mp);
11270   W (ret);
11271   return ret;
11272 }
11273
11274 static int
11275 api_set_ipfix_exporter (vat_main_t * vam)
11276 {
11277   unformat_input_t *i = vam->input;
11278   vl_api_set_ipfix_exporter_t *mp;
11279   ip4_address_t collector_address;
11280   u8 collector_address_set = 0;
11281   u32 collector_port = ~0;
11282   ip4_address_t src_address;
11283   u8 src_address_set = 0;
11284   u32 vrf_id = ~0;
11285   u32 path_mtu = ~0;
11286   u32 template_interval = ~0;
11287   u8 udp_checksum = 0;
11288   int ret;
11289
11290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (unformat (i, "collector_address %U", unformat_ip4_address,
11293                     &collector_address))
11294         collector_address_set = 1;
11295       else if (unformat (i, "collector_port %d", &collector_port))
11296         ;
11297       else if (unformat (i, "src_address %U", unformat_ip4_address,
11298                          &src_address))
11299         src_address_set = 1;
11300       else if (unformat (i, "vrf_id %d", &vrf_id))
11301         ;
11302       else if (unformat (i, "path_mtu %d", &path_mtu))
11303         ;
11304       else if (unformat (i, "template_interval %d", &template_interval))
11305         ;
11306       else if (unformat (i, "udp_checksum"))
11307         udp_checksum = 1;
11308       else
11309         break;
11310     }
11311
11312   if (collector_address_set == 0)
11313     {
11314       errmsg ("collector_address required");
11315       return -99;
11316     }
11317
11318   if (src_address_set == 0)
11319     {
11320       errmsg ("src_address required");
11321       return -99;
11322     }
11323
11324   M (SET_IPFIX_EXPORTER, mp);
11325
11326   memcpy (mp->collector_address, collector_address.data,
11327           sizeof (collector_address.data));
11328   mp->collector_port = htons ((u16) collector_port);
11329   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11330   mp->vrf_id = htonl (vrf_id);
11331   mp->path_mtu = htonl (path_mtu);
11332   mp->template_interval = htonl (template_interval);
11333   mp->udp_checksum = udp_checksum;
11334
11335   S (mp);
11336   W (ret);
11337   return ret;
11338 }
11339
11340 static int
11341 api_set_ipfix_classify_stream (vat_main_t * vam)
11342 {
11343   unformat_input_t *i = vam->input;
11344   vl_api_set_ipfix_classify_stream_t *mp;
11345   u32 domain_id = 0;
11346   u32 src_port = UDP_DST_PORT_ipfix;
11347   int ret;
11348
11349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (i, "domain %d", &domain_id))
11352         ;
11353       else if (unformat (i, "src_port %d", &src_port))
11354         ;
11355       else
11356         {
11357           errmsg ("unknown input `%U'", format_unformat_error, i);
11358           return -99;
11359         }
11360     }
11361
11362   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11363
11364   mp->domain_id = htonl (domain_id);
11365   mp->src_port = htons ((u16) src_port);
11366
11367   S (mp);
11368   W (ret);
11369   return ret;
11370 }
11371
11372 static int
11373 api_ipfix_classify_table_add_del (vat_main_t * vam)
11374 {
11375   unformat_input_t *i = vam->input;
11376   vl_api_ipfix_classify_table_add_del_t *mp;
11377   int is_add = -1;
11378   u32 classify_table_index = ~0;
11379   u8 ip_version = 0;
11380   u8 transport_protocol = 255;
11381   int ret;
11382
11383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11384     {
11385       if (unformat (i, "add"))
11386         is_add = 1;
11387       else if (unformat (i, "del"))
11388         is_add = 0;
11389       else if (unformat (i, "table %d", &classify_table_index))
11390         ;
11391       else if (unformat (i, "ip4"))
11392         ip_version = 4;
11393       else if (unformat (i, "ip6"))
11394         ip_version = 6;
11395       else if (unformat (i, "tcp"))
11396         transport_protocol = 6;
11397       else if (unformat (i, "udp"))
11398         transport_protocol = 17;
11399       else
11400         {
11401           errmsg ("unknown input `%U'", format_unformat_error, i);
11402           return -99;
11403         }
11404     }
11405
11406   if (is_add == -1)
11407     {
11408       errmsg ("expecting: add|del");
11409       return -99;
11410     }
11411   if (classify_table_index == ~0)
11412     {
11413       errmsg ("classifier table not specified");
11414       return -99;
11415     }
11416   if (ip_version == 0)
11417     {
11418       errmsg ("IP version not specified");
11419       return -99;
11420     }
11421
11422   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11423
11424   mp->is_add = is_add;
11425   mp->table_id = htonl (classify_table_index);
11426   mp->ip_version = ip_version;
11427   mp->transport_protocol = transport_protocol;
11428
11429   S (mp);
11430   W (ret);
11431   return ret;
11432 }
11433
11434 static int
11435 api_get_node_index (vat_main_t * vam)
11436 {
11437   unformat_input_t *i = vam->input;
11438   vl_api_get_node_index_t *mp;
11439   u8 *name = 0;
11440   int ret;
11441
11442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (i, "node %s", &name))
11445         ;
11446       else
11447         break;
11448     }
11449   if (name == 0)
11450     {
11451       errmsg ("node name required");
11452       return -99;
11453     }
11454   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11455     {
11456       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11457       return -99;
11458     }
11459
11460   M (GET_NODE_INDEX, mp);
11461   clib_memcpy (mp->node_name, name, vec_len (name));
11462   vec_free (name);
11463
11464   S (mp);
11465   W (ret);
11466   return ret;
11467 }
11468
11469 static int
11470 api_get_next_index (vat_main_t * vam)
11471 {
11472   unformat_input_t *i = vam->input;
11473   vl_api_get_next_index_t *mp;
11474   u8 *node_name = 0, *next_node_name = 0;
11475   int ret;
11476
11477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11478     {
11479       if (unformat (i, "node-name %s", &node_name))
11480         ;
11481       else if (unformat (i, "next-node-name %s", &next_node_name))
11482         break;
11483     }
11484
11485   if (node_name == 0)
11486     {
11487       errmsg ("node name required");
11488       return -99;
11489     }
11490   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11491     {
11492       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11493       return -99;
11494     }
11495
11496   if (next_node_name == 0)
11497     {
11498       errmsg ("next node name required");
11499       return -99;
11500     }
11501   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11502     {
11503       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11504       return -99;
11505     }
11506
11507   M (GET_NEXT_INDEX, mp);
11508   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11509   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11510   vec_free (node_name);
11511   vec_free (next_node_name);
11512
11513   S (mp);
11514   W (ret);
11515   return ret;
11516 }
11517
11518 static int
11519 api_add_node_next (vat_main_t * vam)
11520 {
11521   unformat_input_t *i = vam->input;
11522   vl_api_add_node_next_t *mp;
11523   u8 *name = 0;
11524   u8 *next = 0;
11525   int ret;
11526
11527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11528     {
11529       if (unformat (i, "node %s", &name))
11530         ;
11531       else if (unformat (i, "next %s", &next))
11532         ;
11533       else
11534         break;
11535     }
11536   if (name == 0)
11537     {
11538       errmsg ("node name required");
11539       return -99;
11540     }
11541   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11542     {
11543       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11544       return -99;
11545     }
11546   if (next == 0)
11547     {
11548       errmsg ("next node required");
11549       return -99;
11550     }
11551   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11552     {
11553       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11554       return -99;
11555     }
11556
11557   M (ADD_NODE_NEXT, mp);
11558   clib_memcpy (mp->node_name, name, vec_len (name));
11559   clib_memcpy (mp->next_name, next, vec_len (next));
11560   vec_free (name);
11561   vec_free (next);
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 static int
11569 api_l2tpv3_create_tunnel (vat_main_t * vam)
11570 {
11571   unformat_input_t *i = vam->input;
11572   ip6_address_t client_address, our_address;
11573   int client_address_set = 0;
11574   int our_address_set = 0;
11575   u32 local_session_id = 0;
11576   u32 remote_session_id = 0;
11577   u64 local_cookie = 0;
11578   u64 remote_cookie = 0;
11579   u8 l2_sublayer_present = 0;
11580   vl_api_l2tpv3_create_tunnel_t *mp;
11581   int ret;
11582
11583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (i, "client_address %U", unformat_ip6_address,
11586                     &client_address))
11587         client_address_set = 1;
11588       else if (unformat (i, "our_address %U", unformat_ip6_address,
11589                          &our_address))
11590         our_address_set = 1;
11591       else if (unformat (i, "local_session_id %d", &local_session_id))
11592         ;
11593       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11594         ;
11595       else if (unformat (i, "local_cookie %lld", &local_cookie))
11596         ;
11597       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11598         ;
11599       else if (unformat (i, "l2-sublayer-present"))
11600         l2_sublayer_present = 1;
11601       else
11602         break;
11603     }
11604
11605   if (client_address_set == 0)
11606     {
11607       errmsg ("client_address required");
11608       return -99;
11609     }
11610
11611   if (our_address_set == 0)
11612     {
11613       errmsg ("our_address required");
11614       return -99;
11615     }
11616
11617   M (L2TPV3_CREATE_TUNNEL, mp);
11618
11619   clib_memcpy (mp->client_address, client_address.as_u8,
11620                sizeof (mp->client_address));
11621
11622   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11623
11624   mp->local_session_id = ntohl (local_session_id);
11625   mp->remote_session_id = ntohl (remote_session_id);
11626   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11627   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11628   mp->l2_sublayer_present = l2_sublayer_present;
11629   mp->is_ipv6 = 1;
11630
11631   S (mp);
11632   W (ret);
11633   return ret;
11634 }
11635
11636 static int
11637 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   u32 sw_if_index;
11641   u8 sw_if_index_set = 0;
11642   u64 new_local_cookie = 0;
11643   u64 new_remote_cookie = 0;
11644   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11645   int ret;
11646
11647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11648     {
11649       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11650         sw_if_index_set = 1;
11651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11652         sw_if_index_set = 1;
11653       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11654         ;
11655       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11656         ;
11657       else
11658         break;
11659     }
11660
11661   if (sw_if_index_set == 0)
11662     {
11663       errmsg ("missing interface name or sw_if_index");
11664       return -99;
11665     }
11666
11667   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11668
11669   mp->sw_if_index = ntohl (sw_if_index);
11670   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11671   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11672
11673   S (mp);
11674   W (ret);
11675   return ret;
11676 }
11677
11678 static int
11679 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11680 {
11681   unformat_input_t *i = vam->input;
11682   vl_api_l2tpv3_interface_enable_disable_t *mp;
11683   u32 sw_if_index;
11684   u8 sw_if_index_set = 0;
11685   u8 enable_disable = 1;
11686   int ret;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11691         sw_if_index_set = 1;
11692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11693         sw_if_index_set = 1;
11694       else if (unformat (i, "enable"))
11695         enable_disable = 1;
11696       else if (unformat (i, "disable"))
11697         enable_disable = 0;
11698       else
11699         break;
11700     }
11701
11702   if (sw_if_index_set == 0)
11703     {
11704       errmsg ("missing interface name or sw_if_index");
11705       return -99;
11706     }
11707
11708   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11709
11710   mp->sw_if_index = ntohl (sw_if_index);
11711   mp->enable_disable = enable_disable;
11712
11713   S (mp);
11714   W (ret);
11715   return ret;
11716 }
11717
11718 static int
11719 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11720 {
11721   unformat_input_t *i = vam->input;
11722   vl_api_l2tpv3_set_lookup_key_t *mp;
11723   u8 key = ~0;
11724   int ret;
11725
11726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11727     {
11728       if (unformat (i, "lookup_v6_src"))
11729         key = L2T_LOOKUP_SRC_ADDRESS;
11730       else if (unformat (i, "lookup_v6_dst"))
11731         key = L2T_LOOKUP_DST_ADDRESS;
11732       else if (unformat (i, "lookup_session_id"))
11733         key = L2T_LOOKUP_SESSION_ID;
11734       else
11735         break;
11736     }
11737
11738   if (key == (u8) ~ 0)
11739     {
11740       errmsg ("l2tp session lookup key unset");
11741       return -99;
11742     }
11743
11744   M (L2TPV3_SET_LOOKUP_KEY, mp);
11745
11746   mp->key = key;
11747
11748   S (mp);
11749   W (ret);
11750   return ret;
11751 }
11752
11753 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11754   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11755 {
11756   vat_main_t *vam = &vat_main;
11757
11758   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11759          format_ip6_address, mp->our_address,
11760          format_ip6_address, mp->client_address,
11761          clib_net_to_host_u32 (mp->sw_if_index));
11762
11763   print (vam->ofp,
11764          "   local cookies %016llx %016llx remote cookie %016llx",
11765          clib_net_to_host_u64 (mp->local_cookie[0]),
11766          clib_net_to_host_u64 (mp->local_cookie[1]),
11767          clib_net_to_host_u64 (mp->remote_cookie));
11768
11769   print (vam->ofp, "   local session-id %d remote session-id %d",
11770          clib_net_to_host_u32 (mp->local_session_id),
11771          clib_net_to_host_u32 (mp->remote_session_id));
11772
11773   print (vam->ofp, "   l2 specific sublayer %s\n",
11774          mp->l2_sublayer_present ? "preset" : "absent");
11775
11776 }
11777
11778 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11779   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11780 {
11781   vat_main_t *vam = &vat_main;
11782   vat_json_node_t *node = NULL;
11783   struct in6_addr addr;
11784
11785   if (VAT_JSON_ARRAY != vam->json_tree.type)
11786     {
11787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11788       vat_json_init_array (&vam->json_tree);
11789     }
11790   node = vat_json_array_add (&vam->json_tree);
11791
11792   vat_json_init_object (node);
11793
11794   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11795   vat_json_object_add_ip6 (node, "our_address", addr);
11796   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11797   vat_json_object_add_ip6 (node, "client_address", addr);
11798
11799   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11800   vat_json_init_array (lc);
11801   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11802   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11803   vat_json_object_add_uint (node, "remote_cookie",
11804                             clib_net_to_host_u64 (mp->remote_cookie));
11805
11806   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11807   vat_json_object_add_uint (node, "local_session_id",
11808                             clib_net_to_host_u32 (mp->local_session_id));
11809   vat_json_object_add_uint (node, "remote_session_id",
11810                             clib_net_to_host_u32 (mp->remote_session_id));
11811   vat_json_object_add_string_copy (node, "l2_sublayer",
11812                                    mp->l2_sublayer_present ? (u8 *) "present"
11813                                    : (u8 *) "absent");
11814 }
11815
11816 static int
11817 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11818 {
11819   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11820   vl_api_control_ping_t *mp_ping;
11821   int ret;
11822
11823   /* Get list of l2tpv3-tunnel interfaces */
11824   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11825   S (mp);
11826
11827   /* Use a control ping for synchronization */
11828   MPING (CONTROL_PING, mp_ping);
11829   S (mp_ping);
11830
11831   W (ret);
11832   return ret;
11833 }
11834
11835
11836 static void vl_api_sw_interface_tap_details_t_handler
11837   (vl_api_sw_interface_tap_details_t * mp)
11838 {
11839   vat_main_t *vam = &vat_main;
11840
11841   print (vam->ofp, "%-16s %d",
11842          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11843 }
11844
11845 static void vl_api_sw_interface_tap_details_t_handler_json
11846   (vl_api_sw_interface_tap_details_t * mp)
11847 {
11848   vat_main_t *vam = &vat_main;
11849   vat_json_node_t *node = NULL;
11850
11851   if (VAT_JSON_ARRAY != vam->json_tree.type)
11852     {
11853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11854       vat_json_init_array (&vam->json_tree);
11855     }
11856   node = vat_json_array_add (&vam->json_tree);
11857
11858   vat_json_init_object (node);
11859   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11860   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11861 }
11862
11863 static int
11864 api_sw_interface_tap_dump (vat_main_t * vam)
11865 {
11866   vl_api_sw_interface_tap_dump_t *mp;
11867   vl_api_control_ping_t *mp_ping;
11868   int ret;
11869
11870   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11871   /* Get list of tap interfaces */
11872   M (SW_INTERFACE_TAP_DUMP, mp);
11873   S (mp);
11874
11875   /* Use a control ping for synchronization */
11876   MPING (CONTROL_PING, mp_ping);
11877   S (mp_ping);
11878
11879   W (ret);
11880   return ret;
11881 }
11882
11883 static uword unformat_vxlan_decap_next
11884   (unformat_input_t * input, va_list * args)
11885 {
11886   u32 *result = va_arg (*args, u32 *);
11887   u32 tmp;
11888
11889   if (unformat (input, "l2"))
11890     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11891   else if (unformat (input, "%d", &tmp))
11892     *result = tmp;
11893   else
11894     return 0;
11895   return 1;
11896 }
11897
11898 static int
11899 api_vxlan_add_del_tunnel (vat_main_t * vam)
11900 {
11901   unformat_input_t *line_input = vam->input;
11902   vl_api_vxlan_add_del_tunnel_t *mp;
11903   ip46_address_t src, dst;
11904   u8 is_add = 1;
11905   u8 ipv4_set = 0, ipv6_set = 0;
11906   u8 src_set = 0;
11907   u8 dst_set = 0;
11908   u8 grp_set = 0;
11909   u32 mcast_sw_if_index = ~0;
11910   u32 encap_vrf_id = 0;
11911   u32 decap_next_index = ~0;
11912   u32 vni = 0;
11913   int ret;
11914
11915   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11916   memset (&src, 0, sizeof src);
11917   memset (&dst, 0, sizeof dst);
11918
11919   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11920     {
11921       if (unformat (line_input, "del"))
11922         is_add = 0;
11923       else
11924         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11925         {
11926           ipv4_set = 1;
11927           src_set = 1;
11928         }
11929       else
11930         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11931         {
11932           ipv4_set = 1;
11933           dst_set = 1;
11934         }
11935       else
11936         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11937         {
11938           ipv6_set = 1;
11939           src_set = 1;
11940         }
11941       else
11942         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11943         {
11944           ipv6_set = 1;
11945           dst_set = 1;
11946         }
11947       else if (unformat (line_input, "group %U %U",
11948                          unformat_ip4_address, &dst.ip4,
11949                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11950         {
11951           grp_set = dst_set = 1;
11952           ipv4_set = 1;
11953         }
11954       else if (unformat (line_input, "group %U",
11955                          unformat_ip4_address, &dst.ip4))
11956         {
11957           grp_set = dst_set = 1;
11958           ipv4_set = 1;
11959         }
11960       else if (unformat (line_input, "group %U %U",
11961                          unformat_ip6_address, &dst.ip6,
11962                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11963         {
11964           grp_set = dst_set = 1;
11965           ipv6_set = 1;
11966         }
11967       else if (unformat (line_input, "group %U",
11968                          unformat_ip6_address, &dst.ip6))
11969         {
11970           grp_set = dst_set = 1;
11971           ipv6_set = 1;
11972         }
11973       else
11974         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11975         ;
11976       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11977         ;
11978       else if (unformat (line_input, "decap-next %U",
11979                          unformat_vxlan_decap_next, &decap_next_index))
11980         ;
11981       else if (unformat (line_input, "vni %d", &vni))
11982         ;
11983       else
11984         {
11985           errmsg ("parse error '%U'", format_unformat_error, line_input);
11986           return -99;
11987         }
11988     }
11989
11990   if (src_set == 0)
11991     {
11992       errmsg ("tunnel src address not specified");
11993       return -99;
11994     }
11995   if (dst_set == 0)
11996     {
11997       errmsg ("tunnel dst address not specified");
11998       return -99;
11999     }
12000
12001   if (grp_set && !ip46_address_is_multicast (&dst))
12002     {
12003       errmsg ("tunnel group address not multicast");
12004       return -99;
12005     }
12006   if (grp_set && mcast_sw_if_index == ~0)
12007     {
12008       errmsg ("tunnel nonexistent multicast device");
12009       return -99;
12010     }
12011   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12012     {
12013       errmsg ("tunnel dst address must be unicast");
12014       return -99;
12015     }
12016
12017
12018   if (ipv4_set && ipv6_set)
12019     {
12020       errmsg ("both IPv4 and IPv6 addresses specified");
12021       return -99;
12022     }
12023
12024   if ((vni == 0) || (vni >> 24))
12025     {
12026       errmsg ("vni not specified or out of range");
12027       return -99;
12028     }
12029
12030   M (VXLAN_ADD_DEL_TUNNEL, mp);
12031
12032   if (ipv6_set)
12033     {
12034       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12035       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12036     }
12037   else
12038     {
12039       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12040       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12041     }
12042   mp->encap_vrf_id = ntohl (encap_vrf_id);
12043   mp->decap_next_index = ntohl (decap_next_index);
12044   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12045   mp->vni = ntohl (vni);
12046   mp->is_add = is_add;
12047   mp->is_ipv6 = ipv6_set;
12048
12049   S (mp);
12050   W (ret);
12051   return ret;
12052 }
12053
12054 static void vl_api_vxlan_tunnel_details_t_handler
12055   (vl_api_vxlan_tunnel_details_t * mp)
12056 {
12057   vat_main_t *vam = &vat_main;
12058   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12059   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12060
12061   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12062          ntohl (mp->sw_if_index),
12063          format_ip46_address, &src, IP46_TYPE_ANY,
12064          format_ip46_address, &dst, IP46_TYPE_ANY,
12065          ntohl (mp->encap_vrf_id),
12066          ntohl (mp->decap_next_index), ntohl (mp->vni),
12067          ntohl (mp->mcast_sw_if_index));
12068 }
12069
12070 static void vl_api_vxlan_tunnel_details_t_handler_json
12071   (vl_api_vxlan_tunnel_details_t * mp)
12072 {
12073   vat_main_t *vam = &vat_main;
12074   vat_json_node_t *node = NULL;
12075
12076   if (VAT_JSON_ARRAY != vam->json_tree.type)
12077     {
12078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12079       vat_json_init_array (&vam->json_tree);
12080     }
12081   node = vat_json_array_add (&vam->json_tree);
12082
12083   vat_json_init_object (node);
12084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12085   if (mp->is_ipv6)
12086     {
12087       struct in6_addr ip6;
12088
12089       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12090       vat_json_object_add_ip6 (node, "src_address", ip6);
12091       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12092       vat_json_object_add_ip6 (node, "dst_address", ip6);
12093     }
12094   else
12095     {
12096       struct in_addr ip4;
12097
12098       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12099       vat_json_object_add_ip4 (node, "src_address", ip4);
12100       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12101       vat_json_object_add_ip4 (node, "dst_address", ip4);
12102     }
12103   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12104   vat_json_object_add_uint (node, "decap_next_index",
12105                             ntohl (mp->decap_next_index));
12106   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12107   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12108   vat_json_object_add_uint (node, "mcast_sw_if_index",
12109                             ntohl (mp->mcast_sw_if_index));
12110 }
12111
12112 static int
12113 api_vxlan_tunnel_dump (vat_main_t * vam)
12114 {
12115   unformat_input_t *i = vam->input;
12116   vl_api_vxlan_tunnel_dump_t *mp;
12117   vl_api_control_ping_t *mp_ping;
12118   u32 sw_if_index;
12119   u8 sw_if_index_set = 0;
12120   int ret;
12121
12122   /* Parse args required to build the message */
12123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12124     {
12125       if (unformat (i, "sw_if_index %d", &sw_if_index))
12126         sw_if_index_set = 1;
12127       else
12128         break;
12129     }
12130
12131   if (sw_if_index_set == 0)
12132     {
12133       sw_if_index = ~0;
12134     }
12135
12136   if (!vam->json_output)
12137     {
12138       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12139              "sw_if_index", "src_address", "dst_address",
12140              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12141     }
12142
12143   /* Get list of vxlan-tunnel interfaces */
12144   M (VXLAN_TUNNEL_DUMP, mp);
12145
12146   mp->sw_if_index = htonl (sw_if_index);
12147
12148   S (mp);
12149
12150   /* Use a control ping for synchronization */
12151   MPING (CONTROL_PING, mp_ping);
12152   S (mp_ping);
12153
12154   W (ret);
12155   return ret;
12156 }
12157
12158 static uword unformat_geneve_decap_next
12159   (unformat_input_t * input, va_list * args)
12160 {
12161   u32 *result = va_arg (*args, u32 *);
12162   u32 tmp;
12163
12164   if (unformat (input, "l2"))
12165     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12166   else if (unformat (input, "%d", &tmp))
12167     *result = tmp;
12168   else
12169     return 0;
12170   return 1;
12171 }
12172
12173 static int
12174 api_geneve_add_del_tunnel (vat_main_t * vam)
12175 {
12176   unformat_input_t *line_input = vam->input;
12177   vl_api_geneve_add_del_tunnel_t *mp;
12178   ip46_address_t src, dst;
12179   u8 is_add = 1;
12180   u8 ipv4_set = 0, ipv6_set = 0;
12181   u8 src_set = 0;
12182   u8 dst_set = 0;
12183   u8 grp_set = 0;
12184   u32 mcast_sw_if_index = ~0;
12185   u32 encap_vrf_id = 0;
12186   u32 decap_next_index = ~0;
12187   u32 vni = 0;
12188   int ret;
12189
12190   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12191   memset (&src, 0, sizeof src);
12192   memset (&dst, 0, sizeof dst);
12193
12194   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12195     {
12196       if (unformat (line_input, "del"))
12197         is_add = 0;
12198       else
12199         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12200         {
12201           ipv4_set = 1;
12202           src_set = 1;
12203         }
12204       else
12205         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12206         {
12207           ipv4_set = 1;
12208           dst_set = 1;
12209         }
12210       else
12211         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12212         {
12213           ipv6_set = 1;
12214           src_set = 1;
12215         }
12216       else
12217         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12218         {
12219           ipv6_set = 1;
12220           dst_set = 1;
12221         }
12222       else if (unformat (line_input, "group %U %U",
12223                          unformat_ip4_address, &dst.ip4,
12224                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12225         {
12226           grp_set = dst_set = 1;
12227           ipv4_set = 1;
12228         }
12229       else if (unformat (line_input, "group %U",
12230                          unformat_ip4_address, &dst.ip4))
12231         {
12232           grp_set = dst_set = 1;
12233           ipv4_set = 1;
12234         }
12235       else if (unformat (line_input, "group %U %U",
12236                          unformat_ip6_address, &dst.ip6,
12237                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12238         {
12239           grp_set = dst_set = 1;
12240           ipv6_set = 1;
12241         }
12242       else if (unformat (line_input, "group %U",
12243                          unformat_ip6_address, &dst.ip6))
12244         {
12245           grp_set = dst_set = 1;
12246           ipv6_set = 1;
12247         }
12248       else
12249         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12250         ;
12251       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12252         ;
12253       else if (unformat (line_input, "decap-next %U",
12254                          unformat_geneve_decap_next, &decap_next_index))
12255         ;
12256       else if (unformat (line_input, "vni %d", &vni))
12257         ;
12258       else
12259         {
12260           errmsg ("parse error '%U'", format_unformat_error, line_input);
12261           return -99;
12262         }
12263     }
12264
12265   if (src_set == 0)
12266     {
12267       errmsg ("tunnel src address not specified");
12268       return -99;
12269     }
12270   if (dst_set == 0)
12271     {
12272       errmsg ("tunnel dst address not specified");
12273       return -99;
12274     }
12275
12276   if (grp_set && !ip46_address_is_multicast (&dst))
12277     {
12278       errmsg ("tunnel group address not multicast");
12279       return -99;
12280     }
12281   if (grp_set && mcast_sw_if_index == ~0)
12282     {
12283       errmsg ("tunnel nonexistent multicast device");
12284       return -99;
12285     }
12286   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12287     {
12288       errmsg ("tunnel dst address must be unicast");
12289       return -99;
12290     }
12291
12292
12293   if (ipv4_set && ipv6_set)
12294     {
12295       errmsg ("both IPv4 and IPv6 addresses specified");
12296       return -99;
12297     }
12298
12299   if ((vni == 0) || (vni >> 24))
12300     {
12301       errmsg ("vni not specified or out of range");
12302       return -99;
12303     }
12304
12305   M (GENEVE_ADD_DEL_TUNNEL, mp);
12306
12307   if (ipv6_set)
12308     {
12309       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12310       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12311     }
12312   else
12313     {
12314       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12315       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12316     }
12317   mp->encap_vrf_id = ntohl (encap_vrf_id);
12318   mp->decap_next_index = ntohl (decap_next_index);
12319   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12320   mp->vni = ntohl (vni);
12321   mp->is_add = is_add;
12322   mp->is_ipv6 = ipv6_set;
12323
12324   S (mp);
12325   W (ret);
12326   return ret;
12327 }
12328
12329 static void vl_api_geneve_tunnel_details_t_handler
12330   (vl_api_geneve_tunnel_details_t * mp)
12331 {
12332   vat_main_t *vam = &vat_main;
12333   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12334   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12335
12336   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12337          ntohl (mp->sw_if_index),
12338          format_ip46_address, &src, IP46_TYPE_ANY,
12339          format_ip46_address, &dst, IP46_TYPE_ANY,
12340          ntohl (mp->encap_vrf_id),
12341          ntohl (mp->decap_next_index), ntohl (mp->vni),
12342          ntohl (mp->mcast_sw_if_index));
12343 }
12344
12345 static void vl_api_geneve_tunnel_details_t_handler_json
12346   (vl_api_geneve_tunnel_details_t * mp)
12347 {
12348   vat_main_t *vam = &vat_main;
12349   vat_json_node_t *node = NULL;
12350
12351   if (VAT_JSON_ARRAY != vam->json_tree.type)
12352     {
12353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12354       vat_json_init_array (&vam->json_tree);
12355     }
12356   node = vat_json_array_add (&vam->json_tree);
12357
12358   vat_json_init_object (node);
12359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12360   if (mp->is_ipv6)
12361     {
12362       struct in6_addr ip6;
12363
12364       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12365       vat_json_object_add_ip6 (node, "src_address", ip6);
12366       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12367       vat_json_object_add_ip6 (node, "dst_address", ip6);
12368     }
12369   else
12370     {
12371       struct in_addr ip4;
12372
12373       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12374       vat_json_object_add_ip4 (node, "src_address", ip4);
12375       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12376       vat_json_object_add_ip4 (node, "dst_address", ip4);
12377     }
12378   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12379   vat_json_object_add_uint (node, "decap_next_index",
12380                             ntohl (mp->decap_next_index));
12381   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12382   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12383   vat_json_object_add_uint (node, "mcast_sw_if_index",
12384                             ntohl (mp->mcast_sw_if_index));
12385 }
12386
12387 static int
12388 api_geneve_tunnel_dump (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_geneve_tunnel_dump_t *mp;
12392   vl_api_control_ping_t *mp_ping;
12393   u32 sw_if_index;
12394   u8 sw_if_index_set = 0;
12395   int ret;
12396
12397   /* Parse args required to build the message */
12398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12399     {
12400       if (unformat (i, "sw_if_index %d", &sw_if_index))
12401         sw_if_index_set = 1;
12402       else
12403         break;
12404     }
12405
12406   if (sw_if_index_set == 0)
12407     {
12408       sw_if_index = ~0;
12409     }
12410
12411   if (!vam->json_output)
12412     {
12413       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12414              "sw_if_index", "local_address", "remote_address",
12415              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12416     }
12417
12418   /* Get list of geneve-tunnel interfaces */
12419   M (GENEVE_TUNNEL_DUMP, mp);
12420
12421   mp->sw_if_index = htonl (sw_if_index);
12422
12423   S (mp);
12424
12425   /* Use a control ping for synchronization */
12426   M (CONTROL_PING, mp_ping);
12427   S (mp_ping);
12428
12429   W (ret);
12430   return ret;
12431 }
12432
12433 static int
12434 api_gre_add_del_tunnel (vat_main_t * vam)
12435 {
12436   unformat_input_t *line_input = vam->input;
12437   vl_api_gre_add_del_tunnel_t *mp;
12438   ip4_address_t src4, dst4;
12439   ip6_address_t src6, dst6;
12440   u8 is_add = 1;
12441   u8 ipv4_set = 0;
12442   u8 ipv6_set = 0;
12443   u8 teb = 0;
12444   u8 src_set = 0;
12445   u8 dst_set = 0;
12446   u32 outer_fib_id = 0;
12447   int ret;
12448
12449   memset (&src4, 0, sizeof src4);
12450   memset (&dst4, 0, sizeof dst4);
12451   memset (&src6, 0, sizeof src6);
12452   memset (&dst6, 0, sizeof dst6);
12453
12454   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12455     {
12456       if (unformat (line_input, "del"))
12457         is_add = 0;
12458       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12459         {
12460           src_set = 1;
12461           ipv4_set = 1;
12462         }
12463       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12464         {
12465           dst_set = 1;
12466           ipv4_set = 1;
12467         }
12468       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12469         {
12470           src_set = 1;
12471           ipv6_set = 1;
12472         }
12473       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12474         {
12475           dst_set = 1;
12476           ipv6_set = 1;
12477         }
12478       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12479         ;
12480       else if (unformat (line_input, "teb"))
12481         teb = 1;
12482       else
12483         {
12484           errmsg ("parse error '%U'", format_unformat_error, line_input);
12485           return -99;
12486         }
12487     }
12488
12489   if (src_set == 0)
12490     {
12491       errmsg ("tunnel src address not specified");
12492       return -99;
12493     }
12494   if (dst_set == 0)
12495     {
12496       errmsg ("tunnel dst address not specified");
12497       return -99;
12498     }
12499   if (ipv4_set && ipv6_set)
12500     {
12501       errmsg ("both IPv4 and IPv6 addresses specified");
12502       return -99;
12503     }
12504
12505
12506   M (GRE_ADD_DEL_TUNNEL, mp);
12507
12508   if (ipv4_set)
12509     {
12510       clib_memcpy (&mp->src_address, &src4, 4);
12511       clib_memcpy (&mp->dst_address, &dst4, 4);
12512     }
12513   else
12514     {
12515       clib_memcpy (&mp->src_address, &src6, 16);
12516       clib_memcpy (&mp->dst_address, &dst6, 16);
12517     }
12518   mp->outer_fib_id = ntohl (outer_fib_id);
12519   mp->is_add = is_add;
12520   mp->teb = teb;
12521   mp->is_ipv6 = ipv6_set;
12522
12523   S (mp);
12524   W (ret);
12525   return ret;
12526 }
12527
12528 static void vl_api_gre_tunnel_details_t_handler
12529   (vl_api_gre_tunnel_details_t * mp)
12530 {
12531   vat_main_t *vam = &vat_main;
12532   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12533   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12534
12535   print (vam->ofp, "%11d%24U%24U%6d%14d",
12536          ntohl (mp->sw_if_index),
12537          format_ip46_address, &src, IP46_TYPE_ANY,
12538          format_ip46_address, &dst, IP46_TYPE_ANY,
12539          mp->teb, ntohl (mp->outer_fib_id));
12540 }
12541
12542 static void vl_api_gre_tunnel_details_t_handler_json
12543   (vl_api_gre_tunnel_details_t * mp)
12544 {
12545   vat_main_t *vam = &vat_main;
12546   vat_json_node_t *node = NULL;
12547   struct in_addr ip4;
12548   struct in6_addr ip6;
12549
12550   if (VAT_JSON_ARRAY != vam->json_tree.type)
12551     {
12552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12553       vat_json_init_array (&vam->json_tree);
12554     }
12555   node = vat_json_array_add (&vam->json_tree);
12556
12557   vat_json_init_object (node);
12558   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12559   if (!mp->is_ipv6)
12560     {
12561       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12562       vat_json_object_add_ip4 (node, "src_address", ip4);
12563       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12564       vat_json_object_add_ip4 (node, "dst_address", ip4);
12565     }
12566   else
12567     {
12568       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12569       vat_json_object_add_ip6 (node, "src_address", ip6);
12570       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12571       vat_json_object_add_ip6 (node, "dst_address", ip6);
12572     }
12573   vat_json_object_add_uint (node, "teb", mp->teb);
12574   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12575   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12576 }
12577
12578 static int
12579 api_gre_tunnel_dump (vat_main_t * vam)
12580 {
12581   unformat_input_t *i = vam->input;
12582   vl_api_gre_tunnel_dump_t *mp;
12583   vl_api_control_ping_t *mp_ping;
12584   u32 sw_if_index;
12585   u8 sw_if_index_set = 0;
12586   int ret;
12587
12588   /* Parse args required to build the message */
12589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12590     {
12591       if (unformat (i, "sw_if_index %d", &sw_if_index))
12592         sw_if_index_set = 1;
12593       else
12594         break;
12595     }
12596
12597   if (sw_if_index_set == 0)
12598     {
12599       sw_if_index = ~0;
12600     }
12601
12602   if (!vam->json_output)
12603     {
12604       print (vam->ofp, "%11s%24s%24s%6s%14s",
12605              "sw_if_index", "src_address", "dst_address", "teb",
12606              "outer_fib_id");
12607     }
12608
12609   /* Get list of gre-tunnel interfaces */
12610   M (GRE_TUNNEL_DUMP, mp);
12611
12612   mp->sw_if_index = htonl (sw_if_index);
12613
12614   S (mp);
12615
12616   /* Use a control ping for synchronization */
12617   MPING (CONTROL_PING, mp_ping);
12618   S (mp_ping);
12619
12620   W (ret);
12621   return ret;
12622 }
12623
12624 static int
12625 api_l2_fib_clear_table (vat_main_t * vam)
12626 {
12627 //  unformat_input_t * i = vam->input;
12628   vl_api_l2_fib_clear_table_t *mp;
12629   int ret;
12630
12631   M (L2_FIB_CLEAR_TABLE, mp);
12632
12633   S (mp);
12634   W (ret);
12635   return ret;
12636 }
12637
12638 static int
12639 api_l2_interface_efp_filter (vat_main_t * vam)
12640 {
12641   unformat_input_t *i = vam->input;
12642   vl_api_l2_interface_efp_filter_t *mp;
12643   u32 sw_if_index;
12644   u8 enable = 1;
12645   u8 sw_if_index_set = 0;
12646   int ret;
12647
12648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12649     {
12650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12651         sw_if_index_set = 1;
12652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12653         sw_if_index_set = 1;
12654       else if (unformat (i, "enable"))
12655         enable = 1;
12656       else if (unformat (i, "disable"))
12657         enable = 0;
12658       else
12659         {
12660           clib_warning ("parse error '%U'", format_unformat_error, i);
12661           return -99;
12662         }
12663     }
12664
12665   if (sw_if_index_set == 0)
12666     {
12667       errmsg ("missing sw_if_index");
12668       return -99;
12669     }
12670
12671   M (L2_INTERFACE_EFP_FILTER, mp);
12672
12673   mp->sw_if_index = ntohl (sw_if_index);
12674   mp->enable_disable = enable;
12675
12676   S (mp);
12677   W (ret);
12678   return ret;
12679 }
12680
12681 #define foreach_vtr_op                          \
12682 _("disable",  L2_VTR_DISABLED)                  \
12683 _("push-1",  L2_VTR_PUSH_1)                     \
12684 _("push-2",  L2_VTR_PUSH_2)                     \
12685 _("pop-1",  L2_VTR_POP_1)                       \
12686 _("pop-2",  L2_VTR_POP_2)                       \
12687 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12688 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12689 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12690 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12691
12692 static int
12693 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12694 {
12695   unformat_input_t *i = vam->input;
12696   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12697   u32 sw_if_index;
12698   u8 sw_if_index_set = 0;
12699   u8 vtr_op_set = 0;
12700   u32 vtr_op = 0;
12701   u32 push_dot1q = 1;
12702   u32 tag1 = ~0;
12703   u32 tag2 = ~0;
12704   int ret;
12705
12706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12707     {
12708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12709         sw_if_index_set = 1;
12710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12711         sw_if_index_set = 1;
12712       else if (unformat (i, "vtr_op %d", &vtr_op))
12713         vtr_op_set = 1;
12714 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12715       foreach_vtr_op
12716 #undef _
12717         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12718         ;
12719       else if (unformat (i, "tag1 %d", &tag1))
12720         ;
12721       else if (unformat (i, "tag2 %d", &tag2))
12722         ;
12723       else
12724         {
12725           clib_warning ("parse error '%U'", format_unformat_error, i);
12726           return -99;
12727         }
12728     }
12729
12730   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12731     {
12732       errmsg ("missing vtr operation or sw_if_index");
12733       return -99;
12734     }
12735
12736   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12737   mp->sw_if_index = ntohl (sw_if_index);
12738   mp->vtr_op = ntohl (vtr_op);
12739   mp->push_dot1q = ntohl (push_dot1q);
12740   mp->tag1 = ntohl (tag1);
12741   mp->tag2 = ntohl (tag2);
12742
12743   S (mp);
12744   W (ret);
12745   return ret;
12746 }
12747
12748 static int
12749 api_create_vhost_user_if (vat_main_t * vam)
12750 {
12751   unformat_input_t *i = vam->input;
12752   vl_api_create_vhost_user_if_t *mp;
12753   u8 *file_name;
12754   u8 is_server = 0;
12755   u8 file_name_set = 0;
12756   u32 custom_dev_instance = ~0;
12757   u8 hwaddr[6];
12758   u8 use_custom_mac = 0;
12759   u8 *tag = 0;
12760   int ret;
12761
12762   /* Shut up coverity */
12763   memset (hwaddr, 0, sizeof (hwaddr));
12764
12765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12766     {
12767       if (unformat (i, "socket %s", &file_name))
12768         {
12769           file_name_set = 1;
12770         }
12771       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12772         ;
12773       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12774         use_custom_mac = 1;
12775       else if (unformat (i, "server"))
12776         is_server = 1;
12777       else if (unformat (i, "tag %s", &tag))
12778         ;
12779       else
12780         break;
12781     }
12782
12783   if (file_name_set == 0)
12784     {
12785       errmsg ("missing socket file name");
12786       return -99;
12787     }
12788
12789   if (vec_len (file_name) > 255)
12790     {
12791       errmsg ("socket file name too long");
12792       return -99;
12793     }
12794   vec_add1 (file_name, 0);
12795
12796   M (CREATE_VHOST_USER_IF, mp);
12797
12798   mp->is_server = is_server;
12799   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12800   vec_free (file_name);
12801   if (custom_dev_instance != ~0)
12802     {
12803       mp->renumber = 1;
12804       mp->custom_dev_instance = ntohl (custom_dev_instance);
12805     }
12806   mp->use_custom_mac = use_custom_mac;
12807   clib_memcpy (mp->mac_address, hwaddr, 6);
12808   if (tag)
12809     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12810   vec_free (tag);
12811
12812   S (mp);
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static int
12818 api_modify_vhost_user_if (vat_main_t * vam)
12819 {
12820   unformat_input_t *i = vam->input;
12821   vl_api_modify_vhost_user_if_t *mp;
12822   u8 *file_name;
12823   u8 is_server = 0;
12824   u8 file_name_set = 0;
12825   u32 custom_dev_instance = ~0;
12826   u8 sw_if_index_set = 0;
12827   u32 sw_if_index = (u32) ~ 0;
12828   int ret;
12829
12830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12831     {
12832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12833         sw_if_index_set = 1;
12834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12835         sw_if_index_set = 1;
12836       else if (unformat (i, "socket %s", &file_name))
12837         {
12838           file_name_set = 1;
12839         }
12840       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12841         ;
12842       else if (unformat (i, "server"))
12843         is_server = 1;
12844       else
12845         break;
12846     }
12847
12848   if (sw_if_index_set == 0)
12849     {
12850       errmsg ("missing sw_if_index or interface name");
12851       return -99;
12852     }
12853
12854   if (file_name_set == 0)
12855     {
12856       errmsg ("missing socket file name");
12857       return -99;
12858     }
12859
12860   if (vec_len (file_name) > 255)
12861     {
12862       errmsg ("socket file name too long");
12863       return -99;
12864     }
12865   vec_add1 (file_name, 0);
12866
12867   M (MODIFY_VHOST_USER_IF, mp);
12868
12869   mp->sw_if_index = ntohl (sw_if_index);
12870   mp->is_server = is_server;
12871   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12872   vec_free (file_name);
12873   if (custom_dev_instance != ~0)
12874     {
12875       mp->renumber = 1;
12876       mp->custom_dev_instance = ntohl (custom_dev_instance);
12877     }
12878
12879   S (mp);
12880   W (ret);
12881   return ret;
12882 }
12883
12884 static int
12885 api_delete_vhost_user_if (vat_main_t * vam)
12886 {
12887   unformat_input_t *i = vam->input;
12888   vl_api_delete_vhost_user_if_t *mp;
12889   u32 sw_if_index = ~0;
12890   u8 sw_if_index_set = 0;
12891   int ret;
12892
12893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12894     {
12895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12896         sw_if_index_set = 1;
12897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12898         sw_if_index_set = 1;
12899       else
12900         break;
12901     }
12902
12903   if (sw_if_index_set == 0)
12904     {
12905       errmsg ("missing sw_if_index or interface name");
12906       return -99;
12907     }
12908
12909
12910   M (DELETE_VHOST_USER_IF, mp);
12911
12912   mp->sw_if_index = ntohl (sw_if_index);
12913
12914   S (mp);
12915   W (ret);
12916   return ret;
12917 }
12918
12919 static void vl_api_sw_interface_vhost_user_details_t_handler
12920   (vl_api_sw_interface_vhost_user_details_t * mp)
12921 {
12922   vat_main_t *vam = &vat_main;
12923
12924   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12925          (char *) mp->interface_name,
12926          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12927          clib_net_to_host_u64 (mp->features), mp->is_server,
12928          ntohl (mp->num_regions), (char *) mp->sock_filename);
12929   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12930 }
12931
12932 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12933   (vl_api_sw_interface_vhost_user_details_t * mp)
12934 {
12935   vat_main_t *vam = &vat_main;
12936   vat_json_node_t *node = NULL;
12937
12938   if (VAT_JSON_ARRAY != vam->json_tree.type)
12939     {
12940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12941       vat_json_init_array (&vam->json_tree);
12942     }
12943   node = vat_json_array_add (&vam->json_tree);
12944
12945   vat_json_init_object (node);
12946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12947   vat_json_object_add_string_copy (node, "interface_name",
12948                                    mp->interface_name);
12949   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12950                             ntohl (mp->virtio_net_hdr_sz));
12951   vat_json_object_add_uint (node, "features",
12952                             clib_net_to_host_u64 (mp->features));
12953   vat_json_object_add_uint (node, "is_server", mp->is_server);
12954   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12955   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12956   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12957 }
12958
12959 static int
12960 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12961 {
12962   vl_api_sw_interface_vhost_user_dump_t *mp;
12963   vl_api_control_ping_t *mp_ping;
12964   int ret;
12965   print (vam->ofp,
12966          "Interface name            idx hdr_sz features server regions filename");
12967
12968   /* Get list of vhost-user interfaces */
12969   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12970   S (mp);
12971
12972   /* Use a control ping for synchronization */
12973   MPING (CONTROL_PING, mp_ping);
12974   S (mp_ping);
12975
12976   W (ret);
12977   return ret;
12978 }
12979
12980 static int
12981 api_show_version (vat_main_t * vam)
12982 {
12983   vl_api_show_version_t *mp;
12984   int ret;
12985
12986   M (SHOW_VERSION, mp);
12987
12988   S (mp);
12989   W (ret);
12990   return ret;
12991 }
12992
12993
12994 static int
12995 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12996 {
12997   unformat_input_t *line_input = vam->input;
12998   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12999   ip4_address_t local4, remote4;
13000   ip6_address_t local6, remote6;
13001   u8 is_add = 1;
13002   u8 ipv4_set = 0, ipv6_set = 0;
13003   u8 local_set = 0;
13004   u8 remote_set = 0;
13005   u8 grp_set = 0;
13006   u32 mcast_sw_if_index = ~0;
13007   u32 encap_vrf_id = 0;
13008   u32 decap_vrf_id = 0;
13009   u8 protocol = ~0;
13010   u32 vni;
13011   u8 vni_set = 0;
13012   int ret;
13013
13014   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13015   memset (&local4, 0, sizeof local4);
13016   memset (&remote4, 0, sizeof remote4);
13017   memset (&local6, 0, sizeof local6);
13018   memset (&remote6, 0, sizeof remote6);
13019
13020   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13021     {
13022       if (unformat (line_input, "del"))
13023         is_add = 0;
13024       else if (unformat (line_input, "local %U",
13025                          unformat_ip4_address, &local4))
13026         {
13027           local_set = 1;
13028           ipv4_set = 1;
13029         }
13030       else if (unformat (line_input, "remote %U",
13031                          unformat_ip4_address, &remote4))
13032         {
13033           remote_set = 1;
13034           ipv4_set = 1;
13035         }
13036       else if (unformat (line_input, "local %U",
13037                          unformat_ip6_address, &local6))
13038         {
13039           local_set = 1;
13040           ipv6_set = 1;
13041         }
13042       else if (unformat (line_input, "remote %U",
13043                          unformat_ip6_address, &remote6))
13044         {
13045           remote_set = 1;
13046           ipv6_set = 1;
13047         }
13048       else if (unformat (line_input, "group %U %U",
13049                          unformat_ip4_address, &remote4,
13050                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13051         {
13052           grp_set = remote_set = 1;
13053           ipv4_set = 1;
13054         }
13055       else if (unformat (line_input, "group %U",
13056                          unformat_ip4_address, &remote4))
13057         {
13058           grp_set = remote_set = 1;
13059           ipv4_set = 1;
13060         }
13061       else if (unformat (line_input, "group %U %U",
13062                          unformat_ip6_address, &remote6,
13063                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13064         {
13065           grp_set = remote_set = 1;
13066           ipv6_set = 1;
13067         }
13068       else if (unformat (line_input, "group %U",
13069                          unformat_ip6_address, &remote6))
13070         {
13071           grp_set = remote_set = 1;
13072           ipv6_set = 1;
13073         }
13074       else
13075         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13076         ;
13077       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13078         ;
13079       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13080         ;
13081       else if (unformat (line_input, "vni %d", &vni))
13082         vni_set = 1;
13083       else if (unformat (line_input, "next-ip4"))
13084         protocol = 1;
13085       else if (unformat (line_input, "next-ip6"))
13086         protocol = 2;
13087       else if (unformat (line_input, "next-ethernet"))
13088         protocol = 3;
13089       else if (unformat (line_input, "next-nsh"))
13090         protocol = 4;
13091       else
13092         {
13093           errmsg ("parse error '%U'", format_unformat_error, line_input);
13094           return -99;
13095         }
13096     }
13097
13098   if (local_set == 0)
13099     {
13100       errmsg ("tunnel local address not specified");
13101       return -99;
13102     }
13103   if (remote_set == 0)
13104     {
13105       errmsg ("tunnel remote address not specified");
13106       return -99;
13107     }
13108   if (grp_set && mcast_sw_if_index == ~0)
13109     {
13110       errmsg ("tunnel nonexistent multicast device");
13111       return -99;
13112     }
13113   if (ipv4_set && ipv6_set)
13114     {
13115       errmsg ("both IPv4 and IPv6 addresses specified");
13116       return -99;
13117     }
13118
13119   if (vni_set == 0)
13120     {
13121       errmsg ("vni not specified");
13122       return -99;
13123     }
13124
13125   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13126
13127
13128   if (ipv6_set)
13129     {
13130       clib_memcpy (&mp->local, &local6, sizeof (local6));
13131       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13132     }
13133   else
13134     {
13135       clib_memcpy (&mp->local, &local4, sizeof (local4));
13136       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13137     }
13138
13139   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13140   mp->encap_vrf_id = ntohl (encap_vrf_id);
13141   mp->decap_vrf_id = ntohl (decap_vrf_id);
13142   mp->protocol = protocol;
13143   mp->vni = ntohl (vni);
13144   mp->is_add = is_add;
13145   mp->is_ipv6 = ipv6_set;
13146
13147   S (mp);
13148   W (ret);
13149   return ret;
13150 }
13151
13152 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13153   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13154 {
13155   vat_main_t *vam = &vat_main;
13156   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13157   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13158
13159   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13160          ntohl (mp->sw_if_index),
13161          format_ip46_address, &local, IP46_TYPE_ANY,
13162          format_ip46_address, &remote, IP46_TYPE_ANY,
13163          ntohl (mp->vni), mp->protocol,
13164          ntohl (mp->mcast_sw_if_index),
13165          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13166 }
13167
13168
13169 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13170   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13171 {
13172   vat_main_t *vam = &vat_main;
13173   vat_json_node_t *node = NULL;
13174   struct in_addr ip4;
13175   struct in6_addr ip6;
13176
13177   if (VAT_JSON_ARRAY != vam->json_tree.type)
13178     {
13179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13180       vat_json_init_array (&vam->json_tree);
13181     }
13182   node = vat_json_array_add (&vam->json_tree);
13183
13184   vat_json_init_object (node);
13185   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13186   if (mp->is_ipv6)
13187     {
13188       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13189       vat_json_object_add_ip6 (node, "local", ip6);
13190       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13191       vat_json_object_add_ip6 (node, "remote", ip6);
13192     }
13193   else
13194     {
13195       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13196       vat_json_object_add_ip4 (node, "local", ip4);
13197       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13198       vat_json_object_add_ip4 (node, "remote", ip4);
13199     }
13200   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13201   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13202   vat_json_object_add_uint (node, "mcast_sw_if_index",
13203                             ntohl (mp->mcast_sw_if_index));
13204   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13205   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13206   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13207 }
13208
13209 static int
13210 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13211 {
13212   unformat_input_t *i = vam->input;
13213   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13214   vl_api_control_ping_t *mp_ping;
13215   u32 sw_if_index;
13216   u8 sw_if_index_set = 0;
13217   int ret;
13218
13219   /* Parse args required to build the message */
13220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13221     {
13222       if (unformat (i, "sw_if_index %d", &sw_if_index))
13223         sw_if_index_set = 1;
13224       else
13225         break;
13226     }
13227
13228   if (sw_if_index_set == 0)
13229     {
13230       sw_if_index = ~0;
13231     }
13232
13233   if (!vam->json_output)
13234     {
13235       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13236              "sw_if_index", "local", "remote", "vni",
13237              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13238     }
13239
13240   /* Get list of vxlan-tunnel interfaces */
13241   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13242
13243   mp->sw_if_index = htonl (sw_if_index);
13244
13245   S (mp);
13246
13247   /* Use a control ping for synchronization */
13248   MPING (CONTROL_PING, mp_ping);
13249   S (mp_ping);
13250
13251   W (ret);
13252   return ret;
13253 }
13254
13255
13256 u8 *
13257 format_l2_fib_mac_address (u8 * s, va_list * args)
13258 {
13259   u8 *a = va_arg (*args, u8 *);
13260
13261   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13262                  a[2], a[3], a[4], a[5], a[6], a[7]);
13263 }
13264
13265 static void vl_api_l2_fib_table_details_t_handler
13266   (vl_api_l2_fib_table_details_t * mp)
13267 {
13268   vat_main_t *vam = &vat_main;
13269
13270   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13271          "       %d       %d     %d",
13272          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13273          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13274          mp->bvi_mac);
13275 }
13276
13277 static void vl_api_l2_fib_table_details_t_handler_json
13278   (vl_api_l2_fib_table_details_t * mp)
13279 {
13280   vat_main_t *vam = &vat_main;
13281   vat_json_node_t *node = NULL;
13282
13283   if (VAT_JSON_ARRAY != vam->json_tree.type)
13284     {
13285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13286       vat_json_init_array (&vam->json_tree);
13287     }
13288   node = vat_json_array_add (&vam->json_tree);
13289
13290   vat_json_init_object (node);
13291   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13292   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13294   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13295   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13296   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13297 }
13298
13299 static int
13300 api_l2_fib_table_dump (vat_main_t * vam)
13301 {
13302   unformat_input_t *i = vam->input;
13303   vl_api_l2_fib_table_dump_t *mp;
13304   vl_api_control_ping_t *mp_ping;
13305   u32 bd_id;
13306   u8 bd_id_set = 0;
13307   int ret;
13308
13309   /* Parse args required to build the message */
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "bd_id %d", &bd_id))
13313         bd_id_set = 1;
13314       else
13315         break;
13316     }
13317
13318   if (bd_id_set == 0)
13319     {
13320       errmsg ("missing bridge domain");
13321       return -99;
13322     }
13323
13324   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13325
13326   /* Get list of l2 fib entries */
13327   M (L2_FIB_TABLE_DUMP, mp);
13328
13329   mp->bd_id = ntohl (bd_id);
13330   S (mp);
13331
13332   /* Use a control ping for synchronization */
13333   MPING (CONTROL_PING, mp_ping);
13334   S (mp_ping);
13335
13336   W (ret);
13337   return ret;
13338 }
13339
13340
13341 static int
13342 api_interface_name_renumber (vat_main_t * vam)
13343 {
13344   unformat_input_t *line_input = vam->input;
13345   vl_api_interface_name_renumber_t *mp;
13346   u32 sw_if_index = ~0;
13347   u32 new_show_dev_instance = ~0;
13348   int ret;
13349
13350   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13351     {
13352       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13353                     &sw_if_index))
13354         ;
13355       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13356         ;
13357       else if (unformat (line_input, "new_show_dev_instance %d",
13358                          &new_show_dev_instance))
13359         ;
13360       else
13361         break;
13362     }
13363
13364   if (sw_if_index == ~0)
13365     {
13366       errmsg ("missing interface name or sw_if_index");
13367       return -99;
13368     }
13369
13370   if (new_show_dev_instance == ~0)
13371     {
13372       errmsg ("missing new_show_dev_instance");
13373       return -99;
13374     }
13375
13376   M (INTERFACE_NAME_RENUMBER, mp);
13377
13378   mp->sw_if_index = ntohl (sw_if_index);
13379   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13380
13381   S (mp);
13382   W (ret);
13383   return ret;
13384 }
13385
13386 static int
13387 api_want_ip4_arp_events (vat_main_t * vam)
13388 {
13389   unformat_input_t *line_input = vam->input;
13390   vl_api_want_ip4_arp_events_t *mp;
13391   ip4_address_t address;
13392   int address_set = 0;
13393   u32 enable_disable = 1;
13394   int ret;
13395
13396   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13397     {
13398       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13399         address_set = 1;
13400       else if (unformat (line_input, "del"))
13401         enable_disable = 0;
13402       else
13403         break;
13404     }
13405
13406   if (address_set == 0)
13407     {
13408       errmsg ("missing addresses");
13409       return -99;
13410     }
13411
13412   M (WANT_IP4_ARP_EVENTS, mp);
13413   mp->enable_disable = enable_disable;
13414   mp->pid = htonl (getpid ());
13415   mp->address = address.as_u32;
13416
13417   S (mp);
13418   W (ret);
13419   return ret;
13420 }
13421
13422 static int
13423 api_want_ip6_nd_events (vat_main_t * vam)
13424 {
13425   unformat_input_t *line_input = vam->input;
13426   vl_api_want_ip6_nd_events_t *mp;
13427   ip6_address_t address;
13428   int address_set = 0;
13429   u32 enable_disable = 1;
13430   int ret;
13431
13432   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13433     {
13434       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13435         address_set = 1;
13436       else if (unformat (line_input, "del"))
13437         enable_disable = 0;
13438       else
13439         break;
13440     }
13441
13442   if (address_set == 0)
13443     {
13444       errmsg ("missing addresses");
13445       return -99;
13446     }
13447
13448   M (WANT_IP6_ND_EVENTS, mp);
13449   mp->enable_disable = enable_disable;
13450   mp->pid = htonl (getpid ());
13451   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13452
13453   S (mp);
13454   W (ret);
13455   return ret;
13456 }
13457
13458 static int
13459 api_want_l2_macs_events (vat_main_t * vam)
13460 {
13461   unformat_input_t *line_input = vam->input;
13462   vl_api_want_l2_macs_events_t *mp;
13463   u8 enable_disable = 1;
13464   u32 scan_delay = 0;
13465   u32 max_macs_in_event = 0;
13466   u32 learn_limit = 0;
13467   int ret;
13468
13469   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13470     {
13471       if (unformat (line_input, "learn-limit %d", &learn_limit))
13472         ;
13473       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13474         ;
13475       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13476         ;
13477       else if (unformat (line_input, "disable"))
13478         enable_disable = 0;
13479       else
13480         break;
13481     }
13482
13483   M (WANT_L2_MACS_EVENTS, mp);
13484   mp->enable_disable = enable_disable;
13485   mp->pid = htonl (getpid ());
13486   mp->learn_limit = htonl (learn_limit);
13487   mp->scan_delay = (u8) scan_delay;
13488   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13489   S (mp);
13490   W (ret);
13491   return ret;
13492 }
13493
13494 static int
13495 api_input_acl_set_interface (vat_main_t * vam)
13496 {
13497   unformat_input_t *i = vam->input;
13498   vl_api_input_acl_set_interface_t *mp;
13499   u32 sw_if_index;
13500   int sw_if_index_set;
13501   u32 ip4_table_index = ~0;
13502   u32 ip6_table_index = ~0;
13503   u32 l2_table_index = ~0;
13504   u8 is_add = 1;
13505   int ret;
13506
13507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13508     {
13509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13510         sw_if_index_set = 1;
13511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13512         sw_if_index_set = 1;
13513       else if (unformat (i, "del"))
13514         is_add = 0;
13515       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13516         ;
13517       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13518         ;
13519       else if (unformat (i, "l2-table %d", &l2_table_index))
13520         ;
13521       else
13522         {
13523           clib_warning ("parse error '%U'", format_unformat_error, i);
13524           return -99;
13525         }
13526     }
13527
13528   if (sw_if_index_set == 0)
13529     {
13530       errmsg ("missing interface name or sw_if_index");
13531       return -99;
13532     }
13533
13534   M (INPUT_ACL_SET_INTERFACE, mp);
13535
13536   mp->sw_if_index = ntohl (sw_if_index);
13537   mp->ip4_table_index = ntohl (ip4_table_index);
13538   mp->ip6_table_index = ntohl (ip6_table_index);
13539   mp->l2_table_index = ntohl (l2_table_index);
13540   mp->is_add = is_add;
13541
13542   S (mp);
13543   W (ret);
13544   return ret;
13545 }
13546
13547 static int
13548 api_ip_address_dump (vat_main_t * vam)
13549 {
13550   unformat_input_t *i = vam->input;
13551   vl_api_ip_address_dump_t *mp;
13552   vl_api_control_ping_t *mp_ping;
13553   u32 sw_if_index = ~0;
13554   u8 sw_if_index_set = 0;
13555   u8 ipv4_set = 0;
13556   u8 ipv6_set = 0;
13557   int ret;
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "sw_if_index %d", &sw_if_index))
13562         sw_if_index_set = 1;
13563       else
13564         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13565         sw_if_index_set = 1;
13566       else if (unformat (i, "ipv4"))
13567         ipv4_set = 1;
13568       else if (unformat (i, "ipv6"))
13569         ipv6_set = 1;
13570       else
13571         break;
13572     }
13573
13574   if (ipv4_set && ipv6_set)
13575     {
13576       errmsg ("ipv4 and ipv6 flags cannot be both set");
13577       return -99;
13578     }
13579
13580   if ((!ipv4_set) && (!ipv6_set))
13581     {
13582       errmsg ("no ipv4 nor ipv6 flag set");
13583       return -99;
13584     }
13585
13586   if (sw_if_index_set == 0)
13587     {
13588       errmsg ("missing interface name or sw_if_index");
13589       return -99;
13590     }
13591
13592   vam->current_sw_if_index = sw_if_index;
13593   vam->is_ipv6 = ipv6_set;
13594
13595   M (IP_ADDRESS_DUMP, mp);
13596   mp->sw_if_index = ntohl (sw_if_index);
13597   mp->is_ipv6 = ipv6_set;
13598   S (mp);
13599
13600   /* Use a control ping for synchronization */
13601   MPING (CONTROL_PING, mp_ping);
13602   S (mp_ping);
13603
13604   W (ret);
13605   return ret;
13606 }
13607
13608 static int
13609 api_ip_dump (vat_main_t * vam)
13610 {
13611   vl_api_ip_dump_t *mp;
13612   vl_api_control_ping_t *mp_ping;
13613   unformat_input_t *in = vam->input;
13614   int ipv4_set = 0;
13615   int ipv6_set = 0;
13616   int is_ipv6;
13617   int i;
13618   int ret;
13619
13620   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13621     {
13622       if (unformat (in, "ipv4"))
13623         ipv4_set = 1;
13624       else if (unformat (in, "ipv6"))
13625         ipv6_set = 1;
13626       else
13627         break;
13628     }
13629
13630   if (ipv4_set && ipv6_set)
13631     {
13632       errmsg ("ipv4 and ipv6 flags cannot be both set");
13633       return -99;
13634     }
13635
13636   if ((!ipv4_set) && (!ipv6_set))
13637     {
13638       errmsg ("no ipv4 nor ipv6 flag set");
13639       return -99;
13640     }
13641
13642   is_ipv6 = ipv6_set;
13643   vam->is_ipv6 = is_ipv6;
13644
13645   /* free old data */
13646   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13647     {
13648       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13649     }
13650   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13651
13652   M (IP_DUMP, mp);
13653   mp->is_ipv6 = ipv6_set;
13654   S (mp);
13655
13656   /* Use a control ping for synchronization */
13657   MPING (CONTROL_PING, mp_ping);
13658   S (mp_ping);
13659
13660   W (ret);
13661   return ret;
13662 }
13663
13664 static int
13665 api_ipsec_spd_add_del (vat_main_t * vam)
13666 {
13667   unformat_input_t *i = vam->input;
13668   vl_api_ipsec_spd_add_del_t *mp;
13669   u32 spd_id = ~0;
13670   u8 is_add = 1;
13671   int ret;
13672
13673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13674     {
13675       if (unformat (i, "spd_id %d", &spd_id))
13676         ;
13677       else if (unformat (i, "del"))
13678         is_add = 0;
13679       else
13680         {
13681           clib_warning ("parse error '%U'", format_unformat_error, i);
13682           return -99;
13683         }
13684     }
13685   if (spd_id == ~0)
13686     {
13687       errmsg ("spd_id must be set");
13688       return -99;
13689     }
13690
13691   M (IPSEC_SPD_ADD_DEL, mp);
13692
13693   mp->spd_id = ntohl (spd_id);
13694   mp->is_add = is_add;
13695
13696   S (mp);
13697   W (ret);
13698   return ret;
13699 }
13700
13701 static int
13702 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13703 {
13704   unformat_input_t *i = vam->input;
13705   vl_api_ipsec_interface_add_del_spd_t *mp;
13706   u32 sw_if_index;
13707   u8 sw_if_index_set = 0;
13708   u32 spd_id = (u32) ~ 0;
13709   u8 is_add = 1;
13710   int ret;
13711
13712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13713     {
13714       if (unformat (i, "del"))
13715         is_add = 0;
13716       else if (unformat (i, "spd_id %d", &spd_id))
13717         ;
13718       else
13719         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13720         sw_if_index_set = 1;
13721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13722         sw_if_index_set = 1;
13723       else
13724         {
13725           clib_warning ("parse error '%U'", format_unformat_error, i);
13726           return -99;
13727         }
13728
13729     }
13730
13731   if (spd_id == (u32) ~ 0)
13732     {
13733       errmsg ("spd_id must be set");
13734       return -99;
13735     }
13736
13737   if (sw_if_index_set == 0)
13738     {
13739       errmsg ("missing interface name or sw_if_index");
13740       return -99;
13741     }
13742
13743   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13744
13745   mp->spd_id = ntohl (spd_id);
13746   mp->sw_if_index = ntohl (sw_if_index);
13747   mp->is_add = is_add;
13748
13749   S (mp);
13750   W (ret);
13751   return ret;
13752 }
13753
13754 static int
13755 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13756 {
13757   unformat_input_t *i = vam->input;
13758   vl_api_ipsec_spd_add_del_entry_t *mp;
13759   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13760   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13761   i32 priority = 0;
13762   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13763   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13764   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13765   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13766   int ret;
13767
13768   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13769   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13770   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13771   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13772   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13773   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13774
13775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13776     {
13777       if (unformat (i, "del"))
13778         is_add = 0;
13779       if (unformat (i, "outbound"))
13780         is_outbound = 1;
13781       if (unformat (i, "inbound"))
13782         is_outbound = 0;
13783       else if (unformat (i, "spd_id %d", &spd_id))
13784         ;
13785       else if (unformat (i, "sa_id %d", &sa_id))
13786         ;
13787       else if (unformat (i, "priority %d", &priority))
13788         ;
13789       else if (unformat (i, "protocol %d", &protocol))
13790         ;
13791       else if (unformat (i, "lport_start %d", &lport_start))
13792         ;
13793       else if (unformat (i, "lport_stop %d", &lport_stop))
13794         ;
13795       else if (unformat (i, "rport_start %d", &rport_start))
13796         ;
13797       else if (unformat (i, "rport_stop %d", &rport_stop))
13798         ;
13799       else
13800         if (unformat
13801             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13802         {
13803           is_ipv6 = 0;
13804           is_ip_any = 0;
13805         }
13806       else
13807         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13808         {
13809           is_ipv6 = 0;
13810           is_ip_any = 0;
13811         }
13812       else
13813         if (unformat
13814             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13815         {
13816           is_ipv6 = 0;
13817           is_ip_any = 0;
13818         }
13819       else
13820         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13821         {
13822           is_ipv6 = 0;
13823           is_ip_any = 0;
13824         }
13825       else
13826         if (unformat
13827             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13828         {
13829           is_ipv6 = 1;
13830           is_ip_any = 0;
13831         }
13832       else
13833         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13834         {
13835           is_ipv6 = 1;
13836           is_ip_any = 0;
13837         }
13838       else
13839         if (unformat
13840             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13841         {
13842           is_ipv6 = 1;
13843           is_ip_any = 0;
13844         }
13845       else
13846         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13847         {
13848           is_ipv6 = 1;
13849           is_ip_any = 0;
13850         }
13851       else
13852         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13853         {
13854           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13855             {
13856               clib_warning ("unsupported action: 'resolve'");
13857               return -99;
13858             }
13859         }
13860       else
13861         {
13862           clib_warning ("parse error '%U'", format_unformat_error, i);
13863           return -99;
13864         }
13865
13866     }
13867
13868   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13869
13870   mp->spd_id = ntohl (spd_id);
13871   mp->priority = ntohl (priority);
13872   mp->is_outbound = is_outbound;
13873
13874   mp->is_ipv6 = is_ipv6;
13875   if (is_ipv6 || is_ip_any)
13876     {
13877       clib_memcpy (mp->remote_address_start, &raddr6_start,
13878                    sizeof (ip6_address_t));
13879       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13880                    sizeof (ip6_address_t));
13881       clib_memcpy (mp->local_address_start, &laddr6_start,
13882                    sizeof (ip6_address_t));
13883       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13884                    sizeof (ip6_address_t));
13885     }
13886   else
13887     {
13888       clib_memcpy (mp->remote_address_start, &raddr4_start,
13889                    sizeof (ip4_address_t));
13890       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13891                    sizeof (ip4_address_t));
13892       clib_memcpy (mp->local_address_start, &laddr4_start,
13893                    sizeof (ip4_address_t));
13894       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13895                    sizeof (ip4_address_t));
13896     }
13897   mp->protocol = (u8) protocol;
13898   mp->local_port_start = ntohs ((u16) lport_start);
13899   mp->local_port_stop = ntohs ((u16) lport_stop);
13900   mp->remote_port_start = ntohs ((u16) rport_start);
13901   mp->remote_port_stop = ntohs ((u16) rport_stop);
13902   mp->policy = (u8) policy;
13903   mp->sa_id = ntohl (sa_id);
13904   mp->is_add = is_add;
13905   mp->is_ip_any = is_ip_any;
13906   S (mp);
13907   W (ret);
13908   return ret;
13909 }
13910
13911 static int
13912 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13913 {
13914   unformat_input_t *i = vam->input;
13915   vl_api_ipsec_sad_add_del_entry_t *mp;
13916   u32 sad_id = 0, spi = 0;
13917   u8 *ck = 0, *ik = 0;
13918   u8 is_add = 1;
13919
13920   u8 protocol = IPSEC_PROTOCOL_AH;
13921   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13922   u32 crypto_alg = 0, integ_alg = 0;
13923   ip4_address_t tun_src4;
13924   ip4_address_t tun_dst4;
13925   ip6_address_t tun_src6;
13926   ip6_address_t tun_dst6;
13927   int ret;
13928
13929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13930     {
13931       if (unformat (i, "del"))
13932         is_add = 0;
13933       else if (unformat (i, "sad_id %d", &sad_id))
13934         ;
13935       else if (unformat (i, "spi %d", &spi))
13936         ;
13937       else if (unformat (i, "esp"))
13938         protocol = IPSEC_PROTOCOL_ESP;
13939       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13940         {
13941           is_tunnel = 1;
13942           is_tunnel_ipv6 = 0;
13943         }
13944       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13945         {
13946           is_tunnel = 1;
13947           is_tunnel_ipv6 = 0;
13948         }
13949       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13950         {
13951           is_tunnel = 1;
13952           is_tunnel_ipv6 = 1;
13953         }
13954       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13955         {
13956           is_tunnel = 1;
13957           is_tunnel_ipv6 = 1;
13958         }
13959       else
13960         if (unformat
13961             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13962         {
13963           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13964               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13965             {
13966               clib_warning ("unsupported crypto-alg: '%U'",
13967                             format_ipsec_crypto_alg, crypto_alg);
13968               return -99;
13969             }
13970         }
13971       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13972         ;
13973       else
13974         if (unformat
13975             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13976         {
13977           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13978               integ_alg >= IPSEC_INTEG_N_ALG)
13979             {
13980               clib_warning ("unsupported integ-alg: '%U'",
13981                             format_ipsec_integ_alg, integ_alg);
13982               return -99;
13983             }
13984         }
13985       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13986         ;
13987       else
13988         {
13989           clib_warning ("parse error '%U'", format_unformat_error, i);
13990           return -99;
13991         }
13992
13993     }
13994
13995   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13996
13997   mp->sad_id = ntohl (sad_id);
13998   mp->is_add = is_add;
13999   mp->protocol = protocol;
14000   mp->spi = ntohl (spi);
14001   mp->is_tunnel = is_tunnel;
14002   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14003   mp->crypto_algorithm = crypto_alg;
14004   mp->integrity_algorithm = integ_alg;
14005   mp->crypto_key_length = vec_len (ck);
14006   mp->integrity_key_length = vec_len (ik);
14007
14008   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14009     mp->crypto_key_length = sizeof (mp->crypto_key);
14010
14011   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14012     mp->integrity_key_length = sizeof (mp->integrity_key);
14013
14014   if (ck)
14015     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14016   if (ik)
14017     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14018
14019   if (is_tunnel)
14020     {
14021       if (is_tunnel_ipv6)
14022         {
14023           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14024                        sizeof (ip6_address_t));
14025           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14026                        sizeof (ip6_address_t));
14027         }
14028       else
14029         {
14030           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14031                        sizeof (ip4_address_t));
14032           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14033                        sizeof (ip4_address_t));
14034         }
14035     }
14036
14037   S (mp);
14038   W (ret);
14039   return ret;
14040 }
14041
14042 static int
14043 api_ipsec_sa_set_key (vat_main_t * vam)
14044 {
14045   unformat_input_t *i = vam->input;
14046   vl_api_ipsec_sa_set_key_t *mp;
14047   u32 sa_id;
14048   u8 *ck = 0, *ik = 0;
14049   int ret;
14050
14051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (i, "sa_id %d", &sa_id))
14054         ;
14055       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14056         ;
14057       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14058         ;
14059       else
14060         {
14061           clib_warning ("parse error '%U'", format_unformat_error, i);
14062           return -99;
14063         }
14064     }
14065
14066   M (IPSEC_SA_SET_KEY, mp);
14067
14068   mp->sa_id = ntohl (sa_id);
14069   mp->crypto_key_length = vec_len (ck);
14070   mp->integrity_key_length = vec_len (ik);
14071
14072   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14073     mp->crypto_key_length = sizeof (mp->crypto_key);
14074
14075   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14076     mp->integrity_key_length = sizeof (mp->integrity_key);
14077
14078   if (ck)
14079     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14080   if (ik)
14081     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14082
14083   S (mp);
14084   W (ret);
14085   return ret;
14086 }
14087
14088 static int
14089 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14090 {
14091   unformat_input_t *i = vam->input;
14092   vl_api_ipsec_tunnel_if_add_del_t *mp;
14093   u32 local_spi = 0, remote_spi = 0;
14094   u32 crypto_alg = 0, integ_alg = 0;
14095   u8 *lck = NULL, *rck = NULL;
14096   u8 *lik = NULL, *rik = NULL;
14097   ip4_address_t local_ip = { {0} };
14098   ip4_address_t remote_ip = { {0} };
14099   u8 is_add = 1;
14100   u8 esn = 0;
14101   u8 anti_replay = 0;
14102   int ret;
14103
14104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14105     {
14106       if (unformat (i, "del"))
14107         is_add = 0;
14108       else if (unformat (i, "esn"))
14109         esn = 1;
14110       else if (unformat (i, "anti_replay"))
14111         anti_replay = 1;
14112       else if (unformat (i, "local_spi %d", &local_spi))
14113         ;
14114       else if (unformat (i, "remote_spi %d", &remote_spi))
14115         ;
14116       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14117         ;
14118       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14119         ;
14120       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14121         ;
14122       else
14123         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14124         ;
14125       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14126         ;
14127       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14128         ;
14129       else
14130         if (unformat
14131             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14132         {
14133           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14134               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14135             {
14136               errmsg ("unsupported crypto-alg: '%U'\n",
14137                       format_ipsec_crypto_alg, crypto_alg);
14138               return -99;
14139             }
14140         }
14141       else
14142         if (unformat
14143             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14144         {
14145           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14146               integ_alg >= IPSEC_INTEG_N_ALG)
14147             {
14148               errmsg ("unsupported integ-alg: '%U'\n",
14149                       format_ipsec_integ_alg, integ_alg);
14150               return -99;
14151             }
14152         }
14153       else
14154         {
14155           errmsg ("parse error '%U'\n", format_unformat_error, i);
14156           return -99;
14157         }
14158     }
14159
14160   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14161
14162   mp->is_add = is_add;
14163   mp->esn = esn;
14164   mp->anti_replay = anti_replay;
14165
14166   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14167   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14168
14169   mp->local_spi = htonl (local_spi);
14170   mp->remote_spi = htonl (remote_spi);
14171   mp->crypto_alg = (u8) crypto_alg;
14172
14173   mp->local_crypto_key_len = 0;
14174   if (lck)
14175     {
14176       mp->local_crypto_key_len = vec_len (lck);
14177       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14178         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14179       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14180     }
14181
14182   mp->remote_crypto_key_len = 0;
14183   if (rck)
14184     {
14185       mp->remote_crypto_key_len = vec_len (rck);
14186       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14187         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14188       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14189     }
14190
14191   mp->integ_alg = (u8) integ_alg;
14192
14193   mp->local_integ_key_len = 0;
14194   if (lik)
14195     {
14196       mp->local_integ_key_len = vec_len (lik);
14197       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14198         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14199       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14200     }
14201
14202   mp->remote_integ_key_len = 0;
14203   if (rik)
14204     {
14205       mp->remote_integ_key_len = vec_len (rik);
14206       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14207         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14208       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14209     }
14210
14211   S (mp);
14212   W (ret);
14213   return ret;
14214 }
14215
14216 static void
14217 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14218 {
14219   vat_main_t *vam = &vat_main;
14220
14221   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14222          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14223          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14224          "tunnel_src_addr %U tunnel_dst_addr %U "
14225          "salt %u seq_outbound %lu last_seq_inbound %lu "
14226          "replay_window %lu total_data_size %lu\n",
14227          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14228          mp->protocol,
14229          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14230          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14231          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14232          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14233          mp->tunnel_src_addr,
14234          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14235          mp->tunnel_dst_addr,
14236          ntohl (mp->salt),
14237          clib_net_to_host_u64 (mp->seq_outbound),
14238          clib_net_to_host_u64 (mp->last_seq_inbound),
14239          clib_net_to_host_u64 (mp->replay_window),
14240          clib_net_to_host_u64 (mp->total_data_size));
14241 }
14242
14243 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14244 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14245
14246 static void vl_api_ipsec_sa_details_t_handler_json
14247   (vl_api_ipsec_sa_details_t * mp)
14248 {
14249   vat_main_t *vam = &vat_main;
14250   vat_json_node_t *node = NULL;
14251   struct in_addr src_ip4, dst_ip4;
14252   struct in6_addr src_ip6, dst_ip6;
14253
14254   if (VAT_JSON_ARRAY != vam->json_tree.type)
14255     {
14256       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14257       vat_json_init_array (&vam->json_tree);
14258     }
14259   node = vat_json_array_add (&vam->json_tree);
14260
14261   vat_json_init_object (node);
14262   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14263   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14264   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14265   vat_json_object_add_uint (node, "proto", mp->protocol);
14266   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14267   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14268   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14269   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14270   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14271   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14272   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14273                              mp->crypto_key_len);
14274   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14275                              mp->integ_key_len);
14276   if (mp->is_tunnel_ip6)
14277     {
14278       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14279       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14280       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14281       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14282     }
14283   else
14284     {
14285       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14286       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14287       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14288       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14289     }
14290   vat_json_object_add_uint (node, "replay_window",
14291                             clib_net_to_host_u64 (mp->replay_window));
14292   vat_json_object_add_uint (node, "total_data_size",
14293                             clib_net_to_host_u64 (mp->total_data_size));
14294
14295 }
14296
14297 static int
14298 api_ipsec_sa_dump (vat_main_t * vam)
14299 {
14300   unformat_input_t *i = vam->input;
14301   vl_api_ipsec_sa_dump_t *mp;
14302   vl_api_control_ping_t *mp_ping;
14303   u32 sa_id = ~0;
14304   int ret;
14305
14306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (i, "sa_id %d", &sa_id))
14309         ;
14310       else
14311         {
14312           clib_warning ("parse error '%U'", format_unformat_error, i);
14313           return -99;
14314         }
14315     }
14316
14317   M (IPSEC_SA_DUMP, mp);
14318
14319   mp->sa_id = ntohl (sa_id);
14320
14321   S (mp);
14322
14323   /* Use a control ping for synchronization */
14324   M (CONTROL_PING, mp_ping);
14325   S (mp_ping);
14326
14327   W (ret);
14328   return ret;
14329 }
14330
14331 static int
14332 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14333 {
14334   unformat_input_t *i = vam->input;
14335   vl_api_ipsec_tunnel_if_set_key_t *mp;
14336   u32 sw_if_index = ~0;
14337   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14338   u8 *key = 0;
14339   u32 alg = ~0;
14340   int ret;
14341
14342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14343     {
14344       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14345         ;
14346       else
14347         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14348         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14349       else
14350         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14351         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14352       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14353         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14354       else
14355         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14356         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14357       else if (unformat (i, "%U", unformat_hex_string, &key))
14358         ;
14359       else
14360         {
14361           clib_warning ("parse error '%U'", format_unformat_error, i);
14362           return -99;
14363         }
14364     }
14365
14366   if (sw_if_index == ~0)
14367     {
14368       errmsg ("interface must be specified");
14369       return -99;
14370     }
14371
14372   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14373     {
14374       errmsg ("key type must be specified");
14375       return -99;
14376     }
14377
14378   if (alg == ~0)
14379     {
14380       errmsg ("algorithm must be specified");
14381       return -99;
14382     }
14383
14384   if (vec_len (key) == 0)
14385     {
14386       errmsg ("key must be specified");
14387       return -99;
14388     }
14389
14390   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14391
14392   mp->sw_if_index = htonl (sw_if_index);
14393   mp->alg = alg;
14394   mp->key_type = key_type;
14395   mp->key_len = vec_len (key);
14396   clib_memcpy (mp->key, key, vec_len (key));
14397
14398   S (mp);
14399   W (ret);
14400
14401   return ret;
14402 }
14403
14404 static int
14405 api_ikev2_profile_add_del (vat_main_t * vam)
14406 {
14407   unformat_input_t *i = vam->input;
14408   vl_api_ikev2_profile_add_del_t *mp;
14409   u8 is_add = 1;
14410   u8 *name = 0;
14411   int ret;
14412
14413   const char *valid_chars = "a-zA-Z0-9_";
14414
14415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14416     {
14417       if (unformat (i, "del"))
14418         is_add = 0;
14419       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14420         vec_add1 (name, 0);
14421       else
14422         {
14423           errmsg ("parse error '%U'", format_unformat_error, i);
14424           return -99;
14425         }
14426     }
14427
14428   if (!vec_len (name))
14429     {
14430       errmsg ("profile name must be specified");
14431       return -99;
14432     }
14433
14434   if (vec_len (name) > 64)
14435     {
14436       errmsg ("profile name too long");
14437       return -99;
14438     }
14439
14440   M (IKEV2_PROFILE_ADD_DEL, mp);
14441
14442   clib_memcpy (mp->name, name, vec_len (name));
14443   mp->is_add = is_add;
14444   vec_free (name);
14445
14446   S (mp);
14447   W (ret);
14448   return ret;
14449 }
14450
14451 static int
14452 api_ikev2_profile_set_auth (vat_main_t * vam)
14453 {
14454   unformat_input_t *i = vam->input;
14455   vl_api_ikev2_profile_set_auth_t *mp;
14456   u8 *name = 0;
14457   u8 *data = 0;
14458   u32 auth_method = 0;
14459   u8 is_hex = 0;
14460   int ret;
14461
14462   const char *valid_chars = "a-zA-Z0-9_";
14463
14464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14465     {
14466       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14467         vec_add1 (name, 0);
14468       else if (unformat (i, "auth_method %U",
14469                          unformat_ikev2_auth_method, &auth_method))
14470         ;
14471       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14472         is_hex = 1;
14473       else if (unformat (i, "auth_data %v", &data))
14474         ;
14475       else
14476         {
14477           errmsg ("parse error '%U'", format_unformat_error, i);
14478           return -99;
14479         }
14480     }
14481
14482   if (!vec_len (name))
14483     {
14484       errmsg ("profile name must be specified");
14485       return -99;
14486     }
14487
14488   if (vec_len (name) > 64)
14489     {
14490       errmsg ("profile name too long");
14491       return -99;
14492     }
14493
14494   if (!vec_len (data))
14495     {
14496       errmsg ("auth_data must be specified");
14497       return -99;
14498     }
14499
14500   if (!auth_method)
14501     {
14502       errmsg ("auth_method must be specified");
14503       return -99;
14504     }
14505
14506   M (IKEV2_PROFILE_SET_AUTH, mp);
14507
14508   mp->is_hex = is_hex;
14509   mp->auth_method = (u8) auth_method;
14510   mp->data_len = vec_len (data);
14511   clib_memcpy (mp->name, name, vec_len (name));
14512   clib_memcpy (mp->data, data, vec_len (data));
14513   vec_free (name);
14514   vec_free (data);
14515
14516   S (mp);
14517   W (ret);
14518   return ret;
14519 }
14520
14521 static int
14522 api_ikev2_profile_set_id (vat_main_t * vam)
14523 {
14524   unformat_input_t *i = vam->input;
14525   vl_api_ikev2_profile_set_id_t *mp;
14526   u8 *name = 0;
14527   u8 *data = 0;
14528   u8 is_local = 0;
14529   u32 id_type = 0;
14530   ip4_address_t ip4;
14531   int ret;
14532
14533   const char *valid_chars = "a-zA-Z0-9_";
14534
14535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14538         vec_add1 (name, 0);
14539       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14540         ;
14541       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14542         {
14543           data = vec_new (u8, 4);
14544           clib_memcpy (data, ip4.as_u8, 4);
14545         }
14546       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14547         ;
14548       else if (unformat (i, "id_data %v", &data))
14549         ;
14550       else if (unformat (i, "local"))
14551         is_local = 1;
14552       else if (unformat (i, "remote"))
14553         is_local = 0;
14554       else
14555         {
14556           errmsg ("parse error '%U'", format_unformat_error, i);
14557           return -99;
14558         }
14559     }
14560
14561   if (!vec_len (name))
14562     {
14563       errmsg ("profile name must be specified");
14564       return -99;
14565     }
14566
14567   if (vec_len (name) > 64)
14568     {
14569       errmsg ("profile name too long");
14570       return -99;
14571     }
14572
14573   if (!vec_len (data))
14574     {
14575       errmsg ("id_data must be specified");
14576       return -99;
14577     }
14578
14579   if (!id_type)
14580     {
14581       errmsg ("id_type must be specified");
14582       return -99;
14583     }
14584
14585   M (IKEV2_PROFILE_SET_ID, mp);
14586
14587   mp->is_local = is_local;
14588   mp->id_type = (u8) id_type;
14589   mp->data_len = vec_len (data);
14590   clib_memcpy (mp->name, name, vec_len (name));
14591   clib_memcpy (mp->data, data, vec_len (data));
14592   vec_free (name);
14593   vec_free (data);
14594
14595   S (mp);
14596   W (ret);
14597   return ret;
14598 }
14599
14600 static int
14601 api_ikev2_profile_set_ts (vat_main_t * vam)
14602 {
14603   unformat_input_t *i = vam->input;
14604   vl_api_ikev2_profile_set_ts_t *mp;
14605   u8 *name = 0;
14606   u8 is_local = 0;
14607   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14608   ip4_address_t start_addr, end_addr;
14609
14610   const char *valid_chars = "a-zA-Z0-9_";
14611   int ret;
14612
14613   start_addr.as_u32 = 0;
14614   end_addr.as_u32 = (u32) ~ 0;
14615
14616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14617     {
14618       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14619         vec_add1 (name, 0);
14620       else if (unformat (i, "protocol %d", &proto))
14621         ;
14622       else if (unformat (i, "start_port %d", &start_port))
14623         ;
14624       else if (unformat (i, "end_port %d", &end_port))
14625         ;
14626       else
14627         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14628         ;
14629       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14630         ;
14631       else if (unformat (i, "local"))
14632         is_local = 1;
14633       else if (unformat (i, "remote"))
14634         is_local = 0;
14635       else
14636         {
14637           errmsg ("parse error '%U'", format_unformat_error, i);
14638           return -99;
14639         }
14640     }
14641
14642   if (!vec_len (name))
14643     {
14644       errmsg ("profile name must be specified");
14645       return -99;
14646     }
14647
14648   if (vec_len (name) > 64)
14649     {
14650       errmsg ("profile name too long");
14651       return -99;
14652     }
14653
14654   M (IKEV2_PROFILE_SET_TS, mp);
14655
14656   mp->is_local = is_local;
14657   mp->proto = (u8) proto;
14658   mp->start_port = (u16) start_port;
14659   mp->end_port = (u16) end_port;
14660   mp->start_addr = start_addr.as_u32;
14661   mp->end_addr = end_addr.as_u32;
14662   clib_memcpy (mp->name, name, vec_len (name));
14663   vec_free (name);
14664
14665   S (mp);
14666   W (ret);
14667   return ret;
14668 }
14669
14670 static int
14671 api_ikev2_set_local_key (vat_main_t * vam)
14672 {
14673   unformat_input_t *i = vam->input;
14674   vl_api_ikev2_set_local_key_t *mp;
14675   u8 *file = 0;
14676   int ret;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "file %v", &file))
14681         vec_add1 (file, 0);
14682       else
14683         {
14684           errmsg ("parse error '%U'", format_unformat_error, i);
14685           return -99;
14686         }
14687     }
14688
14689   if (!vec_len (file))
14690     {
14691       errmsg ("RSA key file must be specified");
14692       return -99;
14693     }
14694
14695   if (vec_len (file) > 256)
14696     {
14697       errmsg ("file name too long");
14698       return -99;
14699     }
14700
14701   M (IKEV2_SET_LOCAL_KEY, mp);
14702
14703   clib_memcpy (mp->key_file, file, vec_len (file));
14704   vec_free (file);
14705
14706   S (mp);
14707   W (ret);
14708   return ret;
14709 }
14710
14711 static int
14712 api_ikev2_set_responder (vat_main_t * vam)
14713 {
14714   unformat_input_t *i = vam->input;
14715   vl_api_ikev2_set_responder_t *mp;
14716   int ret;
14717   u8 *name = 0;
14718   u32 sw_if_index = ~0;
14719   ip4_address_t address;
14720
14721   const char *valid_chars = "a-zA-Z0-9_";
14722
14723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat
14726           (i, "%U interface %d address %U", unformat_token, valid_chars,
14727            &name, &sw_if_index, unformat_ip4_address, &address))
14728         vec_add1 (name, 0);
14729       else
14730         {
14731           errmsg ("parse error '%U'", format_unformat_error, i);
14732           return -99;
14733         }
14734     }
14735
14736   if (!vec_len (name))
14737     {
14738       errmsg ("profile name must be specified");
14739       return -99;
14740     }
14741
14742   if (vec_len (name) > 64)
14743     {
14744       errmsg ("profile name too long");
14745       return -99;
14746     }
14747
14748   M (IKEV2_SET_RESPONDER, mp);
14749
14750   clib_memcpy (mp->name, name, vec_len (name));
14751   vec_free (name);
14752
14753   mp->sw_if_index = sw_if_index;
14754   clib_memcpy (mp->address, &address, sizeof (address));
14755
14756   S (mp);
14757   W (ret);
14758   return ret;
14759 }
14760
14761 static int
14762 api_ikev2_set_ike_transforms (vat_main_t * vam)
14763 {
14764   unformat_input_t *i = vam->input;
14765   vl_api_ikev2_set_ike_transforms_t *mp;
14766   int ret;
14767   u8 *name = 0;
14768   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14769
14770   const char *valid_chars = "a-zA-Z0-9_";
14771
14772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14773     {
14774       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14775                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14776         vec_add1 (name, 0);
14777       else
14778         {
14779           errmsg ("parse error '%U'", format_unformat_error, i);
14780           return -99;
14781         }
14782     }
14783
14784   if (!vec_len (name))
14785     {
14786       errmsg ("profile name must be specified");
14787       return -99;
14788     }
14789
14790   if (vec_len (name) > 64)
14791     {
14792       errmsg ("profile name too long");
14793       return -99;
14794     }
14795
14796   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14797
14798   clib_memcpy (mp->name, name, vec_len (name));
14799   vec_free (name);
14800   mp->crypto_alg = crypto_alg;
14801   mp->crypto_key_size = crypto_key_size;
14802   mp->integ_alg = integ_alg;
14803   mp->dh_group = dh_group;
14804
14805   S (mp);
14806   W (ret);
14807   return ret;
14808 }
14809
14810
14811 static int
14812 api_ikev2_set_esp_transforms (vat_main_t * vam)
14813 {
14814   unformat_input_t *i = vam->input;
14815   vl_api_ikev2_set_esp_transforms_t *mp;
14816   int ret;
14817   u8 *name = 0;
14818   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14819
14820   const char *valid_chars = "a-zA-Z0-9_";
14821
14822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14823     {
14824       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14825                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14826         vec_add1 (name, 0);
14827       else
14828         {
14829           errmsg ("parse error '%U'", format_unformat_error, i);
14830           return -99;
14831         }
14832     }
14833
14834   if (!vec_len (name))
14835     {
14836       errmsg ("profile name must be specified");
14837       return -99;
14838     }
14839
14840   if (vec_len (name) > 64)
14841     {
14842       errmsg ("profile name too long");
14843       return -99;
14844     }
14845
14846   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14847
14848   clib_memcpy (mp->name, name, vec_len (name));
14849   vec_free (name);
14850   mp->crypto_alg = crypto_alg;
14851   mp->crypto_key_size = crypto_key_size;
14852   mp->integ_alg = integ_alg;
14853   mp->dh_group = dh_group;
14854
14855   S (mp);
14856   W (ret);
14857   return ret;
14858 }
14859
14860 static int
14861 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14862 {
14863   unformat_input_t *i = vam->input;
14864   vl_api_ikev2_set_sa_lifetime_t *mp;
14865   int ret;
14866   u8 *name = 0;
14867   u64 lifetime, lifetime_maxdata;
14868   u32 lifetime_jitter, handover;
14869
14870   const char *valid_chars = "a-zA-Z0-9_";
14871
14872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14873     {
14874       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14875                     &lifetime, &lifetime_jitter, &handover,
14876                     &lifetime_maxdata))
14877         vec_add1 (name, 0);
14878       else
14879         {
14880           errmsg ("parse error '%U'", format_unformat_error, i);
14881           return -99;
14882         }
14883     }
14884
14885   if (!vec_len (name))
14886     {
14887       errmsg ("profile name must be specified");
14888       return -99;
14889     }
14890
14891   if (vec_len (name) > 64)
14892     {
14893       errmsg ("profile name too long");
14894       return -99;
14895     }
14896
14897   M (IKEV2_SET_SA_LIFETIME, mp);
14898
14899   clib_memcpy (mp->name, name, vec_len (name));
14900   vec_free (name);
14901   mp->lifetime = lifetime;
14902   mp->lifetime_jitter = lifetime_jitter;
14903   mp->handover = handover;
14904   mp->lifetime_maxdata = lifetime_maxdata;
14905
14906   S (mp);
14907   W (ret);
14908   return ret;
14909 }
14910
14911 static int
14912 api_ikev2_initiate_sa_init (vat_main_t * vam)
14913 {
14914   unformat_input_t *i = vam->input;
14915   vl_api_ikev2_initiate_sa_init_t *mp;
14916   int ret;
14917   u8 *name = 0;
14918
14919   const char *valid_chars = "a-zA-Z0-9_";
14920
14921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14924         vec_add1 (name, 0);
14925       else
14926         {
14927           errmsg ("parse error '%U'", format_unformat_error, i);
14928           return -99;
14929         }
14930     }
14931
14932   if (!vec_len (name))
14933     {
14934       errmsg ("profile name must be specified");
14935       return -99;
14936     }
14937
14938   if (vec_len (name) > 64)
14939     {
14940       errmsg ("profile name too long");
14941       return -99;
14942     }
14943
14944   M (IKEV2_INITIATE_SA_INIT, mp);
14945
14946   clib_memcpy (mp->name, name, vec_len (name));
14947   vec_free (name);
14948
14949   S (mp);
14950   W (ret);
14951   return ret;
14952 }
14953
14954 static int
14955 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14956 {
14957   unformat_input_t *i = vam->input;
14958   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14959   int ret;
14960   u64 ispi;
14961
14962
14963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (i, "%lx", &ispi))
14966         ;
14967       else
14968         {
14969           errmsg ("parse error '%U'", format_unformat_error, i);
14970           return -99;
14971         }
14972     }
14973
14974   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14975
14976   mp->ispi = ispi;
14977
14978   S (mp);
14979   W (ret);
14980   return ret;
14981 }
14982
14983 static int
14984 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14985 {
14986   unformat_input_t *i = vam->input;
14987   vl_api_ikev2_initiate_del_child_sa_t *mp;
14988   int ret;
14989   u32 ispi;
14990
14991
14992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (i, "%x", &ispi))
14995         ;
14996       else
14997         {
14998           errmsg ("parse error '%U'", format_unformat_error, i);
14999           return -99;
15000         }
15001     }
15002
15003   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15004
15005   mp->ispi = ispi;
15006
15007   S (mp);
15008   W (ret);
15009   return ret;
15010 }
15011
15012 static int
15013 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15014 {
15015   unformat_input_t *i = vam->input;
15016   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15017   int ret;
15018   u32 ispi;
15019
15020
15021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (i, "%x", &ispi))
15024         ;
15025       else
15026         {
15027           errmsg ("parse error '%U'", format_unformat_error, i);
15028           return -99;
15029         }
15030     }
15031
15032   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15033
15034   mp->ispi = ispi;
15035
15036   S (mp);
15037   W (ret);
15038   return ret;
15039 }
15040
15041 /*
15042  * MAP
15043  */
15044 static int
15045 api_map_add_domain (vat_main_t * vam)
15046 {
15047   unformat_input_t *i = vam->input;
15048   vl_api_map_add_domain_t *mp;
15049
15050   ip4_address_t ip4_prefix;
15051   ip6_address_t ip6_prefix;
15052   ip6_address_t ip6_src;
15053   u32 num_m_args = 0;
15054   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15055     0, psid_length = 0;
15056   u8 is_translation = 0;
15057   u32 mtu = 0;
15058   u32 ip6_src_len = 128;
15059   int ret;
15060
15061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15064                     &ip4_prefix, &ip4_prefix_len))
15065         num_m_args++;
15066       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15067                          &ip6_prefix, &ip6_prefix_len))
15068         num_m_args++;
15069       else
15070         if (unformat
15071             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15072              &ip6_src_len))
15073         num_m_args++;
15074       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15075         num_m_args++;
15076       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15077         num_m_args++;
15078       else if (unformat (i, "psid-offset %d", &psid_offset))
15079         num_m_args++;
15080       else if (unformat (i, "psid-len %d", &psid_length))
15081         num_m_args++;
15082       else if (unformat (i, "mtu %d", &mtu))
15083         num_m_args++;
15084       else if (unformat (i, "map-t"))
15085         is_translation = 1;
15086       else
15087         {
15088           clib_warning ("parse error '%U'", format_unformat_error, i);
15089           return -99;
15090         }
15091     }
15092
15093   if (num_m_args < 3)
15094     {
15095       errmsg ("mandatory argument(s) missing");
15096       return -99;
15097     }
15098
15099   /* Construct the API message */
15100   M (MAP_ADD_DOMAIN, mp);
15101
15102   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15103   mp->ip4_prefix_len = ip4_prefix_len;
15104
15105   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15106   mp->ip6_prefix_len = ip6_prefix_len;
15107
15108   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15109   mp->ip6_src_prefix_len = ip6_src_len;
15110
15111   mp->ea_bits_len = ea_bits_len;
15112   mp->psid_offset = psid_offset;
15113   mp->psid_length = psid_length;
15114   mp->is_translation = is_translation;
15115   mp->mtu = htons (mtu);
15116
15117   /* send it... */
15118   S (mp);
15119
15120   /* Wait for a reply, return good/bad news  */
15121   W (ret);
15122   return ret;
15123 }
15124
15125 static int
15126 api_map_del_domain (vat_main_t * vam)
15127 {
15128   unformat_input_t *i = vam->input;
15129   vl_api_map_del_domain_t *mp;
15130
15131   u32 num_m_args = 0;
15132   u32 index;
15133   int ret;
15134
15135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (i, "index %d", &index))
15138         num_m_args++;
15139       else
15140         {
15141           clib_warning ("parse error '%U'", format_unformat_error, i);
15142           return -99;
15143         }
15144     }
15145
15146   if (num_m_args != 1)
15147     {
15148       errmsg ("mandatory argument(s) missing");
15149       return -99;
15150     }
15151
15152   /* Construct the API message */
15153   M (MAP_DEL_DOMAIN, mp);
15154
15155   mp->index = ntohl (index);
15156
15157   /* send it... */
15158   S (mp);
15159
15160   /* Wait for a reply, return good/bad news  */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 static int
15166 api_map_add_del_rule (vat_main_t * vam)
15167 {
15168   unformat_input_t *i = vam->input;
15169   vl_api_map_add_del_rule_t *mp;
15170   u8 is_add = 1;
15171   ip6_address_t ip6_dst;
15172   u32 num_m_args = 0, index, psid = 0;
15173   int ret;
15174
15175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15176     {
15177       if (unformat (i, "index %d", &index))
15178         num_m_args++;
15179       else if (unformat (i, "psid %d", &psid))
15180         num_m_args++;
15181       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15182         num_m_args++;
15183       else if (unformat (i, "del"))
15184         {
15185           is_add = 0;
15186         }
15187       else
15188         {
15189           clib_warning ("parse error '%U'", format_unformat_error, i);
15190           return -99;
15191         }
15192     }
15193
15194   /* Construct the API message */
15195   M (MAP_ADD_DEL_RULE, mp);
15196
15197   mp->index = ntohl (index);
15198   mp->is_add = is_add;
15199   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15200   mp->psid = ntohs (psid);
15201
15202   /* send it... */
15203   S (mp);
15204
15205   /* Wait for a reply, return good/bad news  */
15206   W (ret);
15207   return ret;
15208 }
15209
15210 static int
15211 api_map_domain_dump (vat_main_t * vam)
15212 {
15213   vl_api_map_domain_dump_t *mp;
15214   vl_api_control_ping_t *mp_ping;
15215   int ret;
15216
15217   /* Construct the API message */
15218   M (MAP_DOMAIN_DUMP, mp);
15219
15220   /* send it... */
15221   S (mp);
15222
15223   /* Use a control ping for synchronization */
15224   MPING (CONTROL_PING, mp_ping);
15225   S (mp_ping);
15226
15227   W (ret);
15228   return ret;
15229 }
15230
15231 static int
15232 api_map_rule_dump (vat_main_t * vam)
15233 {
15234   unformat_input_t *i = vam->input;
15235   vl_api_map_rule_dump_t *mp;
15236   vl_api_control_ping_t *mp_ping;
15237   u32 domain_index = ~0;
15238   int ret;
15239
15240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (i, "index %u", &domain_index))
15243         ;
15244       else
15245         break;
15246     }
15247
15248   if (domain_index == ~0)
15249     {
15250       clib_warning ("parse error: domain index expected");
15251       return -99;
15252     }
15253
15254   /* Construct the API message */
15255   M (MAP_RULE_DUMP, mp);
15256
15257   mp->domain_index = htonl (domain_index);
15258
15259   /* send it... */
15260   S (mp);
15261
15262   /* Use a control ping for synchronization */
15263   MPING (CONTROL_PING, mp_ping);
15264   S (mp_ping);
15265
15266   W (ret);
15267   return ret;
15268 }
15269
15270 static void vl_api_map_add_domain_reply_t_handler
15271   (vl_api_map_add_domain_reply_t * mp)
15272 {
15273   vat_main_t *vam = &vat_main;
15274   i32 retval = ntohl (mp->retval);
15275
15276   if (vam->async_mode)
15277     {
15278       vam->async_errors += (retval < 0);
15279     }
15280   else
15281     {
15282       vam->retval = retval;
15283       vam->result_ready = 1;
15284     }
15285 }
15286
15287 static void vl_api_map_add_domain_reply_t_handler_json
15288   (vl_api_map_add_domain_reply_t * mp)
15289 {
15290   vat_main_t *vam = &vat_main;
15291   vat_json_node_t node;
15292
15293   vat_json_init_object (&node);
15294   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15295   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15296
15297   vat_json_print (vam->ofp, &node);
15298   vat_json_free (&node);
15299
15300   vam->retval = ntohl (mp->retval);
15301   vam->result_ready = 1;
15302 }
15303
15304 static int
15305 api_get_first_msg_id (vat_main_t * vam)
15306 {
15307   vl_api_get_first_msg_id_t *mp;
15308   unformat_input_t *i = vam->input;
15309   u8 *name;
15310   u8 name_set = 0;
15311   int ret;
15312
15313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15314     {
15315       if (unformat (i, "client %s", &name))
15316         name_set = 1;
15317       else
15318         break;
15319     }
15320
15321   if (name_set == 0)
15322     {
15323       errmsg ("missing client name");
15324       return -99;
15325     }
15326   vec_add1 (name, 0);
15327
15328   if (vec_len (name) > 63)
15329     {
15330       errmsg ("client name too long");
15331       return -99;
15332     }
15333
15334   M (GET_FIRST_MSG_ID, mp);
15335   clib_memcpy (mp->name, name, vec_len (name));
15336   S (mp);
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_cop_interface_enable_disable (vat_main_t * vam)
15343 {
15344   unformat_input_t *line_input = vam->input;
15345   vl_api_cop_interface_enable_disable_t *mp;
15346   u32 sw_if_index = ~0;
15347   u8 enable_disable = 1;
15348   int ret;
15349
15350   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (line_input, "disable"))
15353         enable_disable = 0;
15354       if (unformat (line_input, "enable"))
15355         enable_disable = 1;
15356       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15357                          vam, &sw_if_index))
15358         ;
15359       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15360         ;
15361       else
15362         break;
15363     }
15364
15365   if (sw_if_index == ~0)
15366     {
15367       errmsg ("missing interface name or sw_if_index");
15368       return -99;
15369     }
15370
15371   /* Construct the API message */
15372   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15373   mp->sw_if_index = ntohl (sw_if_index);
15374   mp->enable_disable = enable_disable;
15375
15376   /* send it... */
15377   S (mp);
15378   /* Wait for the reply */
15379   W (ret);
15380   return ret;
15381 }
15382
15383 static int
15384 api_cop_whitelist_enable_disable (vat_main_t * vam)
15385 {
15386   unformat_input_t *line_input = vam->input;
15387   vl_api_cop_whitelist_enable_disable_t *mp;
15388   u32 sw_if_index = ~0;
15389   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15390   u32 fib_id = 0;
15391   int ret;
15392
15393   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15394     {
15395       if (unformat (line_input, "ip4"))
15396         ip4 = 1;
15397       else if (unformat (line_input, "ip6"))
15398         ip6 = 1;
15399       else if (unformat (line_input, "default"))
15400         default_cop = 1;
15401       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15402                          vam, &sw_if_index))
15403         ;
15404       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15405         ;
15406       else if (unformat (line_input, "fib-id %d", &fib_id))
15407         ;
15408       else
15409         break;
15410     }
15411
15412   if (sw_if_index == ~0)
15413     {
15414       errmsg ("missing interface name or sw_if_index");
15415       return -99;
15416     }
15417
15418   /* Construct the API message */
15419   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15420   mp->sw_if_index = ntohl (sw_if_index);
15421   mp->fib_id = ntohl (fib_id);
15422   mp->ip4 = ip4;
15423   mp->ip6 = ip6;
15424   mp->default_cop = default_cop;
15425
15426   /* send it... */
15427   S (mp);
15428   /* Wait for the reply */
15429   W (ret);
15430   return ret;
15431 }
15432
15433 static int
15434 api_get_node_graph (vat_main_t * vam)
15435 {
15436   vl_api_get_node_graph_t *mp;
15437   int ret;
15438
15439   M (GET_NODE_GRAPH, mp);
15440
15441   /* send it... */
15442   S (mp);
15443   /* Wait for the reply */
15444   W (ret);
15445   return ret;
15446 }
15447
15448 /* *INDENT-OFF* */
15449 /** Used for parsing LISP eids */
15450 typedef CLIB_PACKED(struct{
15451   u8 addr[16];   /**< eid address */
15452   u32 len;       /**< prefix length if IP */
15453   u8 type;      /**< type of eid */
15454 }) lisp_eid_vat_t;
15455 /* *INDENT-ON* */
15456
15457 static uword
15458 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15459 {
15460   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15461
15462   memset (a, 0, sizeof (a[0]));
15463
15464   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15465     {
15466       a->type = 0;              /* ipv4 type */
15467     }
15468   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15469     {
15470       a->type = 1;              /* ipv6 type */
15471     }
15472   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15473     {
15474       a->type = 2;              /* mac type */
15475     }
15476   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15477     {
15478       a->type = 3;              /* NSH type */
15479       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15480       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15481     }
15482   else
15483     {
15484       return 0;
15485     }
15486
15487   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15488     {
15489       return 0;
15490     }
15491
15492   return 1;
15493 }
15494
15495 static int
15496 lisp_eid_size_vat (u8 type)
15497 {
15498   switch (type)
15499     {
15500     case 0:
15501       return 4;
15502     case 1:
15503       return 16;
15504     case 2:
15505       return 6;
15506     case 3:
15507       return 5;
15508     }
15509   return 0;
15510 }
15511
15512 static void
15513 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15514 {
15515   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15516 }
15517
15518 static int
15519 api_one_add_del_locator_set (vat_main_t * vam)
15520 {
15521   unformat_input_t *input = vam->input;
15522   vl_api_one_add_del_locator_set_t *mp;
15523   u8 is_add = 1;
15524   u8 *locator_set_name = NULL;
15525   u8 locator_set_name_set = 0;
15526   vl_api_local_locator_t locator, *locators = 0;
15527   u32 sw_if_index, priority, weight;
15528   u32 data_len = 0;
15529
15530   int ret;
15531   /* Parse args required to build the message */
15532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15533     {
15534       if (unformat (input, "del"))
15535         {
15536           is_add = 0;
15537         }
15538       else if (unformat (input, "locator-set %s", &locator_set_name))
15539         {
15540           locator_set_name_set = 1;
15541         }
15542       else if (unformat (input, "sw_if_index %u p %u w %u",
15543                          &sw_if_index, &priority, &weight))
15544         {
15545           locator.sw_if_index = htonl (sw_if_index);
15546           locator.priority = priority;
15547           locator.weight = weight;
15548           vec_add1 (locators, locator);
15549         }
15550       else
15551         if (unformat
15552             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15553              &sw_if_index, &priority, &weight))
15554         {
15555           locator.sw_if_index = htonl (sw_if_index);
15556           locator.priority = priority;
15557           locator.weight = weight;
15558           vec_add1 (locators, locator);
15559         }
15560       else
15561         break;
15562     }
15563
15564   if (locator_set_name_set == 0)
15565     {
15566       errmsg ("missing locator-set name");
15567       vec_free (locators);
15568       return -99;
15569     }
15570
15571   if (vec_len (locator_set_name) > 64)
15572     {
15573       errmsg ("locator-set name too long");
15574       vec_free (locator_set_name);
15575       vec_free (locators);
15576       return -99;
15577     }
15578   vec_add1 (locator_set_name, 0);
15579
15580   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15581
15582   /* Construct the API message */
15583   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15584
15585   mp->is_add = is_add;
15586   clib_memcpy (mp->locator_set_name, locator_set_name,
15587                vec_len (locator_set_name));
15588   vec_free (locator_set_name);
15589
15590   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15591   if (locators)
15592     clib_memcpy (mp->locators, locators, data_len);
15593   vec_free (locators);
15594
15595   /* send it... */
15596   S (mp);
15597
15598   /* Wait for a reply... */
15599   W (ret);
15600   return ret;
15601 }
15602
15603 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15604
15605 static int
15606 api_one_add_del_locator (vat_main_t * vam)
15607 {
15608   unformat_input_t *input = vam->input;
15609   vl_api_one_add_del_locator_t *mp;
15610   u32 tmp_if_index = ~0;
15611   u32 sw_if_index = ~0;
15612   u8 sw_if_index_set = 0;
15613   u8 sw_if_index_if_name_set = 0;
15614   u32 priority = ~0;
15615   u8 priority_set = 0;
15616   u32 weight = ~0;
15617   u8 weight_set = 0;
15618   u8 is_add = 1;
15619   u8 *locator_set_name = NULL;
15620   u8 locator_set_name_set = 0;
15621   int ret;
15622
15623   /* Parse args required to build the message */
15624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15625     {
15626       if (unformat (input, "del"))
15627         {
15628           is_add = 0;
15629         }
15630       else if (unformat (input, "locator-set %s", &locator_set_name))
15631         {
15632           locator_set_name_set = 1;
15633         }
15634       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15635                          &tmp_if_index))
15636         {
15637           sw_if_index_if_name_set = 1;
15638           sw_if_index = tmp_if_index;
15639         }
15640       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15641         {
15642           sw_if_index_set = 1;
15643           sw_if_index = tmp_if_index;
15644         }
15645       else if (unformat (input, "p %d", &priority))
15646         {
15647           priority_set = 1;
15648         }
15649       else if (unformat (input, "w %d", &weight))
15650         {
15651           weight_set = 1;
15652         }
15653       else
15654         break;
15655     }
15656
15657   if (locator_set_name_set == 0)
15658     {
15659       errmsg ("missing locator-set name");
15660       return -99;
15661     }
15662
15663   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15664     {
15665       errmsg ("missing sw_if_index");
15666       vec_free (locator_set_name);
15667       return -99;
15668     }
15669
15670   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15671     {
15672       errmsg ("cannot use both params interface name and sw_if_index");
15673       vec_free (locator_set_name);
15674       return -99;
15675     }
15676
15677   if (priority_set == 0)
15678     {
15679       errmsg ("missing locator-set priority");
15680       vec_free (locator_set_name);
15681       return -99;
15682     }
15683
15684   if (weight_set == 0)
15685     {
15686       errmsg ("missing locator-set weight");
15687       vec_free (locator_set_name);
15688       return -99;
15689     }
15690
15691   if (vec_len (locator_set_name) > 64)
15692     {
15693       errmsg ("locator-set name too long");
15694       vec_free (locator_set_name);
15695       return -99;
15696     }
15697   vec_add1 (locator_set_name, 0);
15698
15699   /* Construct the API message */
15700   M (ONE_ADD_DEL_LOCATOR, mp);
15701
15702   mp->is_add = is_add;
15703   mp->sw_if_index = ntohl (sw_if_index);
15704   mp->priority = priority;
15705   mp->weight = weight;
15706   clib_memcpy (mp->locator_set_name, locator_set_name,
15707                vec_len (locator_set_name));
15708   vec_free (locator_set_name);
15709
15710   /* send it... */
15711   S (mp);
15712
15713   /* Wait for a reply... */
15714   W (ret);
15715   return ret;
15716 }
15717
15718 #define api_lisp_add_del_locator api_one_add_del_locator
15719
15720 uword
15721 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15722 {
15723   u32 *key_id = va_arg (*args, u32 *);
15724   u8 *s = 0;
15725
15726   if (unformat (input, "%s", &s))
15727     {
15728       if (!strcmp ((char *) s, "sha1"))
15729         key_id[0] = HMAC_SHA_1_96;
15730       else if (!strcmp ((char *) s, "sha256"))
15731         key_id[0] = HMAC_SHA_256_128;
15732       else
15733         {
15734           clib_warning ("invalid key_id: '%s'", s);
15735           key_id[0] = HMAC_NO_KEY;
15736         }
15737     }
15738   else
15739     return 0;
15740
15741   vec_free (s);
15742   return 1;
15743 }
15744
15745 static int
15746 api_one_add_del_local_eid (vat_main_t * vam)
15747 {
15748   unformat_input_t *input = vam->input;
15749   vl_api_one_add_del_local_eid_t *mp;
15750   u8 is_add = 1;
15751   u8 eid_set = 0;
15752   lisp_eid_vat_t _eid, *eid = &_eid;
15753   u8 *locator_set_name = 0;
15754   u8 locator_set_name_set = 0;
15755   u32 vni = 0;
15756   u16 key_id = 0;
15757   u8 *key = 0;
15758   int ret;
15759
15760   /* Parse args required to build the message */
15761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15762     {
15763       if (unformat (input, "del"))
15764         {
15765           is_add = 0;
15766         }
15767       else if (unformat (input, "vni %d", &vni))
15768         {
15769           ;
15770         }
15771       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15772         {
15773           eid_set = 1;
15774         }
15775       else if (unformat (input, "locator-set %s", &locator_set_name))
15776         {
15777           locator_set_name_set = 1;
15778         }
15779       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15780         ;
15781       else if (unformat (input, "secret-key %_%v%_", &key))
15782         ;
15783       else
15784         break;
15785     }
15786
15787   if (locator_set_name_set == 0)
15788     {
15789       errmsg ("missing locator-set name");
15790       return -99;
15791     }
15792
15793   if (0 == eid_set)
15794     {
15795       errmsg ("EID address not set!");
15796       vec_free (locator_set_name);
15797       return -99;
15798     }
15799
15800   if (key && (0 == key_id))
15801     {
15802       errmsg ("invalid key_id!");
15803       return -99;
15804     }
15805
15806   if (vec_len (key) > 64)
15807     {
15808       errmsg ("key too long");
15809       vec_free (key);
15810       return -99;
15811     }
15812
15813   if (vec_len (locator_set_name) > 64)
15814     {
15815       errmsg ("locator-set name too long");
15816       vec_free (locator_set_name);
15817       return -99;
15818     }
15819   vec_add1 (locator_set_name, 0);
15820
15821   /* Construct the API message */
15822   M (ONE_ADD_DEL_LOCAL_EID, mp);
15823
15824   mp->is_add = is_add;
15825   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15826   mp->eid_type = eid->type;
15827   mp->prefix_len = eid->len;
15828   mp->vni = clib_host_to_net_u32 (vni);
15829   mp->key_id = clib_host_to_net_u16 (key_id);
15830   clib_memcpy (mp->locator_set_name, locator_set_name,
15831                vec_len (locator_set_name));
15832   clib_memcpy (mp->key, key, vec_len (key));
15833
15834   vec_free (locator_set_name);
15835   vec_free (key);
15836
15837   /* send it... */
15838   S (mp);
15839
15840   /* Wait for a reply... */
15841   W (ret);
15842   return ret;
15843 }
15844
15845 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15846
15847 static int
15848 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15849 {
15850   u32 dp_table = 0, vni = 0;;
15851   unformat_input_t *input = vam->input;
15852   vl_api_gpe_add_del_fwd_entry_t *mp;
15853   u8 is_add = 1;
15854   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15855   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15856   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15857   u32 action = ~0, w;
15858   ip4_address_t rmt_rloc4, lcl_rloc4;
15859   ip6_address_t rmt_rloc6, lcl_rloc6;
15860   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15861   int ret;
15862
15863   memset (&rloc, 0, sizeof (rloc));
15864
15865   /* Parse args required to build the message */
15866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15867     {
15868       if (unformat (input, "del"))
15869         is_add = 0;
15870       else if (unformat (input, "add"))
15871         is_add = 1;
15872       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15873         {
15874           rmt_eid_set = 1;
15875         }
15876       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15877         {
15878           lcl_eid_set = 1;
15879         }
15880       else if (unformat (input, "vrf %d", &dp_table))
15881         ;
15882       else if (unformat (input, "bd %d", &dp_table))
15883         ;
15884       else if (unformat (input, "vni %d", &vni))
15885         ;
15886       else if (unformat (input, "w %d", &w))
15887         {
15888           if (!curr_rloc)
15889             {
15890               errmsg ("No RLOC configured for setting priority/weight!");
15891               return -99;
15892             }
15893           curr_rloc->weight = w;
15894         }
15895       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15896                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15897         {
15898           rloc.is_ip4 = 1;
15899
15900           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15901           rloc.weight = 0;
15902           vec_add1 (lcl_locs, rloc);
15903
15904           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15905           vec_add1 (rmt_locs, rloc);
15906           /* weight saved in rmt loc */
15907           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15908         }
15909       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15910                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15911         {
15912           rloc.is_ip4 = 0;
15913           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15914           rloc.weight = 0;
15915           vec_add1 (lcl_locs, rloc);
15916
15917           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15918           vec_add1 (rmt_locs, rloc);
15919           /* weight saved in rmt loc */
15920           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15921         }
15922       else if (unformat (input, "action %d", &action))
15923         {
15924           ;
15925         }
15926       else
15927         {
15928           clib_warning ("parse error '%U'", format_unformat_error, input);
15929           return -99;
15930         }
15931     }
15932
15933   if (!rmt_eid_set)
15934     {
15935       errmsg ("remote eid addresses not set");
15936       return -99;
15937     }
15938
15939   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15940     {
15941       errmsg ("eid types don't match");
15942       return -99;
15943     }
15944
15945   if (0 == rmt_locs && (u32) ~ 0 == action)
15946     {
15947       errmsg ("action not set for negative mapping");
15948       return -99;
15949     }
15950
15951   /* Construct the API message */
15952   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15953       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15954
15955   mp->is_add = is_add;
15956   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15957   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15958   mp->eid_type = rmt_eid->type;
15959   mp->dp_table = clib_host_to_net_u32 (dp_table);
15960   mp->vni = clib_host_to_net_u32 (vni);
15961   mp->rmt_len = rmt_eid->len;
15962   mp->lcl_len = lcl_eid->len;
15963   mp->action = action;
15964
15965   if (0 != rmt_locs && 0 != lcl_locs)
15966     {
15967       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15968       clib_memcpy (mp->locs, lcl_locs,
15969                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15970
15971       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15972       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15973                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15974     }
15975   vec_free (lcl_locs);
15976   vec_free (rmt_locs);
15977
15978   /* send it... */
15979   S (mp);
15980
15981   /* Wait for a reply... */
15982   W (ret);
15983   return ret;
15984 }
15985
15986 static int
15987 api_one_add_del_map_server (vat_main_t * vam)
15988 {
15989   unformat_input_t *input = vam->input;
15990   vl_api_one_add_del_map_server_t *mp;
15991   u8 is_add = 1;
15992   u8 ipv4_set = 0;
15993   u8 ipv6_set = 0;
15994   ip4_address_t ipv4;
15995   ip6_address_t ipv6;
15996   int ret;
15997
15998   /* Parse args required to build the message */
15999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16000     {
16001       if (unformat (input, "del"))
16002         {
16003           is_add = 0;
16004         }
16005       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16006         {
16007           ipv4_set = 1;
16008         }
16009       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16010         {
16011           ipv6_set = 1;
16012         }
16013       else
16014         break;
16015     }
16016
16017   if (ipv4_set && ipv6_set)
16018     {
16019       errmsg ("both eid v4 and v6 addresses set");
16020       return -99;
16021     }
16022
16023   if (!ipv4_set && !ipv6_set)
16024     {
16025       errmsg ("eid addresses not set");
16026       return -99;
16027     }
16028
16029   /* Construct the API message */
16030   M (ONE_ADD_DEL_MAP_SERVER, mp);
16031
16032   mp->is_add = is_add;
16033   if (ipv6_set)
16034     {
16035       mp->is_ipv6 = 1;
16036       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16037     }
16038   else
16039     {
16040       mp->is_ipv6 = 0;
16041       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16042     }
16043
16044   /* send it... */
16045   S (mp);
16046
16047   /* Wait for a reply... */
16048   W (ret);
16049   return ret;
16050 }
16051
16052 #define api_lisp_add_del_map_server api_one_add_del_map_server
16053
16054 static int
16055 api_one_add_del_map_resolver (vat_main_t * vam)
16056 {
16057   unformat_input_t *input = vam->input;
16058   vl_api_one_add_del_map_resolver_t *mp;
16059   u8 is_add = 1;
16060   u8 ipv4_set = 0;
16061   u8 ipv6_set = 0;
16062   ip4_address_t ipv4;
16063   ip6_address_t ipv6;
16064   int ret;
16065
16066   /* Parse args required to build the message */
16067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (input, "del"))
16070         {
16071           is_add = 0;
16072         }
16073       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16074         {
16075           ipv4_set = 1;
16076         }
16077       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16078         {
16079           ipv6_set = 1;
16080         }
16081       else
16082         break;
16083     }
16084
16085   if (ipv4_set && ipv6_set)
16086     {
16087       errmsg ("both eid v4 and v6 addresses set");
16088       return -99;
16089     }
16090
16091   if (!ipv4_set && !ipv6_set)
16092     {
16093       errmsg ("eid addresses not set");
16094       return -99;
16095     }
16096
16097   /* Construct the API message */
16098   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16099
16100   mp->is_add = is_add;
16101   if (ipv6_set)
16102     {
16103       mp->is_ipv6 = 1;
16104       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16105     }
16106   else
16107     {
16108       mp->is_ipv6 = 0;
16109       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16110     }
16111
16112   /* send it... */
16113   S (mp);
16114
16115   /* Wait for a reply... */
16116   W (ret);
16117   return ret;
16118 }
16119
16120 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16121
16122 static int
16123 api_lisp_gpe_enable_disable (vat_main_t * vam)
16124 {
16125   unformat_input_t *input = vam->input;
16126   vl_api_gpe_enable_disable_t *mp;
16127   u8 is_set = 0;
16128   u8 is_en = 1;
16129   int ret;
16130
16131   /* Parse args required to build the message */
16132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16133     {
16134       if (unformat (input, "enable"))
16135         {
16136           is_set = 1;
16137           is_en = 1;
16138         }
16139       else if (unformat (input, "disable"))
16140         {
16141           is_set = 1;
16142           is_en = 0;
16143         }
16144       else
16145         break;
16146     }
16147
16148   if (is_set == 0)
16149     {
16150       errmsg ("Value not set");
16151       return -99;
16152     }
16153
16154   /* Construct the API message */
16155   M (GPE_ENABLE_DISABLE, mp);
16156
16157   mp->is_en = is_en;
16158
16159   /* send it... */
16160   S (mp);
16161
16162   /* Wait for a reply... */
16163   W (ret);
16164   return ret;
16165 }
16166
16167 static int
16168 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16169 {
16170   unformat_input_t *input = vam->input;
16171   vl_api_one_rloc_probe_enable_disable_t *mp;
16172   u8 is_set = 0;
16173   u8 is_en = 0;
16174   int ret;
16175
16176   /* Parse args required to build the message */
16177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16178     {
16179       if (unformat (input, "enable"))
16180         {
16181           is_set = 1;
16182           is_en = 1;
16183         }
16184       else if (unformat (input, "disable"))
16185         is_set = 1;
16186       else
16187         break;
16188     }
16189
16190   if (!is_set)
16191     {
16192       errmsg ("Value not set");
16193       return -99;
16194     }
16195
16196   /* Construct the API message */
16197   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16198
16199   mp->is_enabled = is_en;
16200
16201   /* send it... */
16202   S (mp);
16203
16204   /* Wait for a reply... */
16205   W (ret);
16206   return ret;
16207 }
16208
16209 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16210
16211 static int
16212 api_one_map_register_enable_disable (vat_main_t * vam)
16213 {
16214   unformat_input_t *input = vam->input;
16215   vl_api_one_map_register_enable_disable_t *mp;
16216   u8 is_set = 0;
16217   u8 is_en = 0;
16218   int ret;
16219
16220   /* Parse args required to build the message */
16221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (input, "enable"))
16224         {
16225           is_set = 1;
16226           is_en = 1;
16227         }
16228       else if (unformat (input, "disable"))
16229         is_set = 1;
16230       else
16231         break;
16232     }
16233
16234   if (!is_set)
16235     {
16236       errmsg ("Value not set");
16237       return -99;
16238     }
16239
16240   /* Construct the API message */
16241   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16242
16243   mp->is_enabled = is_en;
16244
16245   /* send it... */
16246   S (mp);
16247
16248   /* Wait for a reply... */
16249   W (ret);
16250   return ret;
16251 }
16252
16253 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16254
16255 static int
16256 api_one_enable_disable (vat_main_t * vam)
16257 {
16258   unformat_input_t *input = vam->input;
16259   vl_api_one_enable_disable_t *mp;
16260   u8 is_set = 0;
16261   u8 is_en = 0;
16262   int ret;
16263
16264   /* Parse args required to build the message */
16265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16266     {
16267       if (unformat (input, "enable"))
16268         {
16269           is_set = 1;
16270           is_en = 1;
16271         }
16272       else if (unformat (input, "disable"))
16273         {
16274           is_set = 1;
16275         }
16276       else
16277         break;
16278     }
16279
16280   if (!is_set)
16281     {
16282       errmsg ("Value not set");
16283       return -99;
16284     }
16285
16286   /* Construct the API message */
16287   M (ONE_ENABLE_DISABLE, mp);
16288
16289   mp->is_en = is_en;
16290
16291   /* send it... */
16292   S (mp);
16293
16294   /* Wait for a reply... */
16295   W (ret);
16296   return ret;
16297 }
16298
16299 #define api_lisp_enable_disable api_one_enable_disable
16300
16301 static int
16302 api_show_one_map_register_state (vat_main_t * vam)
16303 {
16304   vl_api_show_one_map_register_state_t *mp;
16305   int ret;
16306
16307   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16308
16309   /* send */
16310   S (mp);
16311
16312   /* wait for reply */
16313   W (ret);
16314   return ret;
16315 }
16316
16317 #define api_show_lisp_map_register_state api_show_one_map_register_state
16318
16319 static int
16320 api_show_one_rloc_probe_state (vat_main_t * vam)
16321 {
16322   vl_api_show_one_rloc_probe_state_t *mp;
16323   int ret;
16324
16325   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16326
16327   /* send */
16328   S (mp);
16329
16330   /* wait for reply */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16336
16337 static int
16338 api_one_add_del_ndp_entry (vat_main_t * vam)
16339 {
16340   vl_api_one_add_del_ndp_entry_t *mp;
16341   unformat_input_t *input = vam->input;
16342   u8 is_add = 1;
16343   u8 mac_set = 0;
16344   u8 bd_set = 0;
16345   u8 ip_set = 0;
16346   u8 mac[6] = { 0, };
16347   u8 ip6[16] = { 0, };
16348   u32 bd = ~0;
16349   int ret;
16350
16351   /* Parse args required to build the message */
16352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16353     {
16354       if (unformat (input, "del"))
16355         is_add = 0;
16356       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16357         mac_set = 1;
16358       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16359         ip_set = 1;
16360       else if (unformat (input, "bd %d", &bd))
16361         bd_set = 1;
16362       else
16363         {
16364           errmsg ("parse error '%U'", format_unformat_error, input);
16365           return -99;
16366         }
16367     }
16368
16369   if (!bd_set || !ip_set || (!mac_set && is_add))
16370     {
16371       errmsg ("Missing BD, IP or MAC!");
16372       return -99;
16373     }
16374
16375   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16376   mp->is_add = is_add;
16377   clib_memcpy (mp->mac, mac, 6);
16378   mp->bd = clib_host_to_net_u32 (bd);
16379   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16380
16381   /* send */
16382   S (mp);
16383
16384   /* wait for reply */
16385   W (ret);
16386   return ret;
16387 }
16388
16389 static int
16390 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16391 {
16392   vl_api_one_add_del_l2_arp_entry_t *mp;
16393   unformat_input_t *input = vam->input;
16394   u8 is_add = 1;
16395   u8 mac_set = 0;
16396   u8 bd_set = 0;
16397   u8 ip_set = 0;
16398   u8 mac[6] = { 0, };
16399   u32 ip4 = 0, bd = ~0;
16400   int ret;
16401
16402   /* Parse args required to build the message */
16403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16404     {
16405       if (unformat (input, "del"))
16406         is_add = 0;
16407       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16408         mac_set = 1;
16409       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16410         ip_set = 1;
16411       else if (unformat (input, "bd %d", &bd))
16412         bd_set = 1;
16413       else
16414         {
16415           errmsg ("parse error '%U'", format_unformat_error, input);
16416           return -99;
16417         }
16418     }
16419
16420   if (!bd_set || !ip_set || (!mac_set && is_add))
16421     {
16422       errmsg ("Missing BD, IP or MAC!");
16423       return -99;
16424     }
16425
16426   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16427   mp->is_add = is_add;
16428   clib_memcpy (mp->mac, mac, 6);
16429   mp->bd = clib_host_to_net_u32 (bd);
16430   mp->ip4 = ip4;
16431
16432   /* send */
16433   S (mp);
16434
16435   /* wait for reply */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 static int
16441 api_one_ndp_bd_get (vat_main_t * vam)
16442 {
16443   vl_api_one_ndp_bd_get_t *mp;
16444   int ret;
16445
16446   M (ONE_NDP_BD_GET, mp);
16447
16448   /* send */
16449   S (mp);
16450
16451   /* wait for reply */
16452   W (ret);
16453   return ret;
16454 }
16455
16456 static int
16457 api_one_ndp_entries_get (vat_main_t * vam)
16458 {
16459   vl_api_one_ndp_entries_get_t *mp;
16460   unformat_input_t *input = vam->input;
16461   u8 bd_set = 0;
16462   u32 bd = ~0;
16463   int ret;
16464
16465   /* Parse args required to build the message */
16466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16467     {
16468       if (unformat (input, "bd %d", &bd))
16469         bd_set = 1;
16470       else
16471         {
16472           errmsg ("parse error '%U'", format_unformat_error, input);
16473           return -99;
16474         }
16475     }
16476
16477   if (!bd_set)
16478     {
16479       errmsg ("Expected bridge domain!");
16480       return -99;
16481     }
16482
16483   M (ONE_NDP_ENTRIES_GET, mp);
16484   mp->bd = clib_host_to_net_u32 (bd);
16485
16486   /* send */
16487   S (mp);
16488
16489   /* wait for reply */
16490   W (ret);
16491   return ret;
16492 }
16493
16494 static int
16495 api_one_l2_arp_bd_get (vat_main_t * vam)
16496 {
16497   vl_api_one_l2_arp_bd_get_t *mp;
16498   int ret;
16499
16500   M (ONE_L2_ARP_BD_GET, mp);
16501
16502   /* send */
16503   S (mp);
16504
16505   /* wait for reply */
16506   W (ret);
16507   return ret;
16508 }
16509
16510 static int
16511 api_one_l2_arp_entries_get (vat_main_t * vam)
16512 {
16513   vl_api_one_l2_arp_entries_get_t *mp;
16514   unformat_input_t *input = vam->input;
16515   u8 bd_set = 0;
16516   u32 bd = ~0;
16517   int ret;
16518
16519   /* Parse args required to build the message */
16520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16521     {
16522       if (unformat (input, "bd %d", &bd))
16523         bd_set = 1;
16524       else
16525         {
16526           errmsg ("parse error '%U'", format_unformat_error, input);
16527           return -99;
16528         }
16529     }
16530
16531   if (!bd_set)
16532     {
16533       errmsg ("Expected bridge domain!");
16534       return -99;
16535     }
16536
16537   M (ONE_L2_ARP_ENTRIES_GET, mp);
16538   mp->bd = clib_host_to_net_u32 (bd);
16539
16540   /* send */
16541   S (mp);
16542
16543   /* wait for reply */
16544   W (ret);
16545   return ret;
16546 }
16547
16548 static int
16549 api_one_stats_enable_disable (vat_main_t * vam)
16550 {
16551   vl_api_one_stats_enable_disable_t *mp;
16552   unformat_input_t *input = vam->input;
16553   u8 is_set = 0;
16554   u8 is_en = 0;
16555   int ret;
16556
16557   /* Parse args required to build the message */
16558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16559     {
16560       if (unformat (input, "enable"))
16561         {
16562           is_set = 1;
16563           is_en = 1;
16564         }
16565       else if (unformat (input, "disable"))
16566         {
16567           is_set = 1;
16568         }
16569       else
16570         break;
16571     }
16572
16573   if (!is_set)
16574     {
16575       errmsg ("Value not set");
16576       return -99;
16577     }
16578
16579   M (ONE_STATS_ENABLE_DISABLE, mp);
16580   mp->is_en = is_en;
16581
16582   /* send */
16583   S (mp);
16584
16585   /* wait for reply */
16586   W (ret);
16587   return ret;
16588 }
16589
16590 static int
16591 api_show_one_stats_enable_disable (vat_main_t * vam)
16592 {
16593   vl_api_show_one_stats_enable_disable_t *mp;
16594   int ret;
16595
16596   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16597
16598   /* send */
16599   S (mp);
16600
16601   /* wait for reply */
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static int
16607 api_show_one_map_request_mode (vat_main_t * vam)
16608 {
16609   vl_api_show_one_map_request_mode_t *mp;
16610   int ret;
16611
16612   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16613
16614   /* send */
16615   S (mp);
16616
16617   /* wait for reply */
16618   W (ret);
16619   return ret;
16620 }
16621
16622 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16623
16624 static int
16625 api_one_map_request_mode (vat_main_t * vam)
16626 {
16627   unformat_input_t *input = vam->input;
16628   vl_api_one_map_request_mode_t *mp;
16629   u8 mode = 0;
16630   int ret;
16631
16632   /* Parse args required to build the message */
16633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16634     {
16635       if (unformat (input, "dst-only"))
16636         mode = 0;
16637       else if (unformat (input, "src-dst"))
16638         mode = 1;
16639       else
16640         {
16641           errmsg ("parse error '%U'", format_unformat_error, input);
16642           return -99;
16643         }
16644     }
16645
16646   M (ONE_MAP_REQUEST_MODE, mp);
16647
16648   mp->mode = mode;
16649
16650   /* send */
16651   S (mp);
16652
16653   /* wait for reply */
16654   W (ret);
16655   return ret;
16656 }
16657
16658 #define api_lisp_map_request_mode api_one_map_request_mode
16659
16660 /**
16661  * Enable/disable ONE proxy ITR.
16662  *
16663  * @param vam vpp API test context
16664  * @return return code
16665  */
16666 static int
16667 api_one_pitr_set_locator_set (vat_main_t * vam)
16668 {
16669   u8 ls_name_set = 0;
16670   unformat_input_t *input = vam->input;
16671   vl_api_one_pitr_set_locator_set_t *mp;
16672   u8 is_add = 1;
16673   u8 *ls_name = 0;
16674   int ret;
16675
16676   /* Parse args required to build the message */
16677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16678     {
16679       if (unformat (input, "del"))
16680         is_add = 0;
16681       else if (unformat (input, "locator-set %s", &ls_name))
16682         ls_name_set = 1;
16683       else
16684         {
16685           errmsg ("parse error '%U'", format_unformat_error, input);
16686           return -99;
16687         }
16688     }
16689
16690   if (!ls_name_set)
16691     {
16692       errmsg ("locator-set name not set!");
16693       return -99;
16694     }
16695
16696   M (ONE_PITR_SET_LOCATOR_SET, mp);
16697
16698   mp->is_add = is_add;
16699   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16700   vec_free (ls_name);
16701
16702   /* send */
16703   S (mp);
16704
16705   /* wait for reply */
16706   W (ret);
16707   return ret;
16708 }
16709
16710 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16711
16712 static int
16713 api_one_nsh_set_locator_set (vat_main_t * vam)
16714 {
16715   u8 ls_name_set = 0;
16716   unformat_input_t *input = vam->input;
16717   vl_api_one_nsh_set_locator_set_t *mp;
16718   u8 is_add = 1;
16719   u8 *ls_name = 0;
16720   int ret;
16721
16722   /* Parse args required to build the message */
16723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16724     {
16725       if (unformat (input, "del"))
16726         is_add = 0;
16727       else if (unformat (input, "ls %s", &ls_name))
16728         ls_name_set = 1;
16729       else
16730         {
16731           errmsg ("parse error '%U'", format_unformat_error, input);
16732           return -99;
16733         }
16734     }
16735
16736   if (!ls_name_set && is_add)
16737     {
16738       errmsg ("locator-set name not set!");
16739       return -99;
16740     }
16741
16742   M (ONE_NSH_SET_LOCATOR_SET, mp);
16743
16744   mp->is_add = is_add;
16745   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16746   vec_free (ls_name);
16747
16748   /* send */
16749   S (mp);
16750
16751   /* wait for reply */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 static int
16757 api_show_one_pitr (vat_main_t * vam)
16758 {
16759   vl_api_show_one_pitr_t *mp;
16760   int ret;
16761
16762   if (!vam->json_output)
16763     {
16764       print (vam->ofp, "%=20s", "lisp status:");
16765     }
16766
16767   M (SHOW_ONE_PITR, mp);
16768   /* send it... */
16769   S (mp);
16770
16771   /* Wait for a reply... */
16772   W (ret);
16773   return ret;
16774 }
16775
16776 #define api_show_lisp_pitr api_show_one_pitr
16777
16778 static int
16779 api_one_use_petr (vat_main_t * vam)
16780 {
16781   unformat_input_t *input = vam->input;
16782   vl_api_one_use_petr_t *mp;
16783   u8 is_add = 0;
16784   ip_address_t ip;
16785   int ret;
16786
16787   memset (&ip, 0, sizeof (ip));
16788
16789   /* Parse args required to build the message */
16790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16791     {
16792       if (unformat (input, "disable"))
16793         is_add = 0;
16794       else
16795         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16796         {
16797           is_add = 1;
16798           ip_addr_version (&ip) = IP4;
16799         }
16800       else
16801         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16802         {
16803           is_add = 1;
16804           ip_addr_version (&ip) = IP6;
16805         }
16806       else
16807         {
16808           errmsg ("parse error '%U'", format_unformat_error, input);
16809           return -99;
16810         }
16811     }
16812
16813   M (ONE_USE_PETR, mp);
16814
16815   mp->is_add = is_add;
16816   if (is_add)
16817     {
16818       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16819       if (mp->is_ip4)
16820         clib_memcpy (mp->address, &ip, 4);
16821       else
16822         clib_memcpy (mp->address, &ip, 16);
16823     }
16824
16825   /* send */
16826   S (mp);
16827
16828   /* wait for reply */
16829   W (ret);
16830   return ret;
16831 }
16832
16833 #define api_lisp_use_petr api_one_use_petr
16834
16835 static int
16836 api_show_one_nsh_mapping (vat_main_t * vam)
16837 {
16838   vl_api_show_one_use_petr_t *mp;
16839   int ret;
16840
16841   if (!vam->json_output)
16842     {
16843       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16844     }
16845
16846   M (SHOW_ONE_NSH_MAPPING, mp);
16847   /* send it... */
16848   S (mp);
16849
16850   /* Wait for a reply... */
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_show_one_use_petr (vat_main_t * vam)
16857 {
16858   vl_api_show_one_use_petr_t *mp;
16859   int ret;
16860
16861   if (!vam->json_output)
16862     {
16863       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16864     }
16865
16866   M (SHOW_ONE_USE_PETR, mp);
16867   /* send it... */
16868   S (mp);
16869
16870   /* Wait for a reply... */
16871   W (ret);
16872   return ret;
16873 }
16874
16875 #define api_show_lisp_use_petr api_show_one_use_petr
16876
16877 /**
16878  * Add/delete mapping between vni and vrf
16879  */
16880 static int
16881 api_one_eid_table_add_del_map (vat_main_t * vam)
16882 {
16883   unformat_input_t *input = vam->input;
16884   vl_api_one_eid_table_add_del_map_t *mp;
16885   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16886   u32 vni, vrf, bd_index;
16887   int ret;
16888
16889   /* Parse args required to build the message */
16890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16891     {
16892       if (unformat (input, "del"))
16893         is_add = 0;
16894       else if (unformat (input, "vrf %d", &vrf))
16895         vrf_set = 1;
16896       else if (unformat (input, "bd_index %d", &bd_index))
16897         bd_index_set = 1;
16898       else if (unformat (input, "vni %d", &vni))
16899         vni_set = 1;
16900       else
16901         break;
16902     }
16903
16904   if (!vni_set || (!vrf_set && !bd_index_set))
16905     {
16906       errmsg ("missing arguments!");
16907       return -99;
16908     }
16909
16910   if (vrf_set && bd_index_set)
16911     {
16912       errmsg ("error: both vrf and bd entered!");
16913       return -99;
16914     }
16915
16916   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16917
16918   mp->is_add = is_add;
16919   mp->vni = htonl (vni);
16920   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16921   mp->is_l2 = bd_index_set;
16922
16923   /* send */
16924   S (mp);
16925
16926   /* wait for reply */
16927   W (ret);
16928   return ret;
16929 }
16930
16931 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16932
16933 uword
16934 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16935 {
16936   u32 *action = va_arg (*args, u32 *);
16937   u8 *s = 0;
16938
16939   if (unformat (input, "%s", &s))
16940     {
16941       if (!strcmp ((char *) s, "no-action"))
16942         action[0] = 0;
16943       else if (!strcmp ((char *) s, "natively-forward"))
16944         action[0] = 1;
16945       else if (!strcmp ((char *) s, "send-map-request"))
16946         action[0] = 2;
16947       else if (!strcmp ((char *) s, "drop"))
16948         action[0] = 3;
16949       else
16950         {
16951           clib_warning ("invalid action: '%s'", s);
16952           action[0] = 3;
16953         }
16954     }
16955   else
16956     return 0;
16957
16958   vec_free (s);
16959   return 1;
16960 }
16961
16962 /**
16963  * Add/del remote mapping to/from ONE control plane
16964  *
16965  * @param vam vpp API test context
16966  * @return return code
16967  */
16968 static int
16969 api_one_add_del_remote_mapping (vat_main_t * vam)
16970 {
16971   unformat_input_t *input = vam->input;
16972   vl_api_one_add_del_remote_mapping_t *mp;
16973   u32 vni = 0;
16974   lisp_eid_vat_t _eid, *eid = &_eid;
16975   lisp_eid_vat_t _seid, *seid = &_seid;
16976   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16977   u32 action = ~0, p, w, data_len;
16978   ip4_address_t rloc4;
16979   ip6_address_t rloc6;
16980   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16981   int ret;
16982
16983   memset (&rloc, 0, sizeof (rloc));
16984
16985   /* Parse args required to build the message */
16986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16987     {
16988       if (unformat (input, "del-all"))
16989         {
16990           del_all = 1;
16991         }
16992       else if (unformat (input, "del"))
16993         {
16994           is_add = 0;
16995         }
16996       else if (unformat (input, "add"))
16997         {
16998           is_add = 1;
16999         }
17000       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17001         {
17002           eid_set = 1;
17003         }
17004       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17005         {
17006           seid_set = 1;
17007         }
17008       else if (unformat (input, "vni %d", &vni))
17009         {
17010           ;
17011         }
17012       else if (unformat (input, "p %d w %d", &p, &w))
17013         {
17014           if (!curr_rloc)
17015             {
17016               errmsg ("No RLOC configured for setting priority/weight!");
17017               return -99;
17018             }
17019           curr_rloc->priority = p;
17020           curr_rloc->weight = w;
17021         }
17022       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17023         {
17024           rloc.is_ip4 = 1;
17025           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17026           vec_add1 (rlocs, rloc);
17027           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17028         }
17029       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17030         {
17031           rloc.is_ip4 = 0;
17032           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17033           vec_add1 (rlocs, rloc);
17034           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17035         }
17036       else if (unformat (input, "action %U",
17037                          unformat_negative_mapping_action, &action))
17038         {
17039           ;
17040         }
17041       else
17042         {
17043           clib_warning ("parse error '%U'", format_unformat_error, input);
17044           return -99;
17045         }
17046     }
17047
17048   if (0 == eid_set)
17049     {
17050       errmsg ("missing params!");
17051       return -99;
17052     }
17053
17054   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17055     {
17056       errmsg ("no action set for negative map-reply!");
17057       return -99;
17058     }
17059
17060   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17061
17062   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17063   mp->is_add = is_add;
17064   mp->vni = htonl (vni);
17065   mp->action = (u8) action;
17066   mp->is_src_dst = seid_set;
17067   mp->eid_len = eid->len;
17068   mp->seid_len = seid->len;
17069   mp->del_all = del_all;
17070   mp->eid_type = eid->type;
17071   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17072   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17073
17074   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17075   clib_memcpy (mp->rlocs, rlocs, data_len);
17076   vec_free (rlocs);
17077
17078   /* send it... */
17079   S (mp);
17080
17081   /* Wait for a reply... */
17082   W (ret);
17083   return ret;
17084 }
17085
17086 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17087
17088 /**
17089  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17090  * forwarding entries in data-plane accordingly.
17091  *
17092  * @param vam vpp API test context
17093  * @return return code
17094  */
17095 static int
17096 api_one_add_del_adjacency (vat_main_t * vam)
17097 {
17098   unformat_input_t *input = vam->input;
17099   vl_api_one_add_del_adjacency_t *mp;
17100   u32 vni = 0;
17101   ip4_address_t leid4, reid4;
17102   ip6_address_t leid6, reid6;
17103   u8 reid_mac[6] = { 0 };
17104   u8 leid_mac[6] = { 0 };
17105   u8 reid_type, leid_type;
17106   u32 leid_len = 0, reid_len = 0, len;
17107   u8 is_add = 1;
17108   int ret;
17109
17110   leid_type = reid_type = (u8) ~ 0;
17111
17112   /* Parse args required to build the message */
17113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17114     {
17115       if (unformat (input, "del"))
17116         {
17117           is_add = 0;
17118         }
17119       else if (unformat (input, "add"))
17120         {
17121           is_add = 1;
17122         }
17123       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17124                          &reid4, &len))
17125         {
17126           reid_type = 0;        /* ipv4 */
17127           reid_len = len;
17128         }
17129       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17130                          &reid6, &len))
17131         {
17132           reid_type = 1;        /* ipv6 */
17133           reid_len = len;
17134         }
17135       else if (unformat (input, "reid %U", unformat_ethernet_address,
17136                          reid_mac))
17137         {
17138           reid_type = 2;        /* mac */
17139         }
17140       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17141                          &leid4, &len))
17142         {
17143           leid_type = 0;        /* ipv4 */
17144           leid_len = len;
17145         }
17146       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17147                          &leid6, &len))
17148         {
17149           leid_type = 1;        /* ipv6 */
17150           leid_len = len;
17151         }
17152       else if (unformat (input, "leid %U", unformat_ethernet_address,
17153                          leid_mac))
17154         {
17155           leid_type = 2;        /* mac */
17156         }
17157       else if (unformat (input, "vni %d", &vni))
17158         {
17159           ;
17160         }
17161       else
17162         {
17163           errmsg ("parse error '%U'", format_unformat_error, input);
17164           return -99;
17165         }
17166     }
17167
17168   if ((u8) ~ 0 == reid_type)
17169     {
17170       errmsg ("missing params!");
17171       return -99;
17172     }
17173
17174   if (leid_type != reid_type)
17175     {
17176       errmsg ("remote and local EIDs are of different types!");
17177       return -99;
17178     }
17179
17180   M (ONE_ADD_DEL_ADJACENCY, mp);
17181   mp->is_add = is_add;
17182   mp->vni = htonl (vni);
17183   mp->leid_len = leid_len;
17184   mp->reid_len = reid_len;
17185   mp->eid_type = reid_type;
17186
17187   switch (mp->eid_type)
17188     {
17189     case 0:
17190       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17191       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17192       break;
17193     case 1:
17194       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17195       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17196       break;
17197     case 2:
17198       clib_memcpy (mp->leid, leid_mac, 6);
17199       clib_memcpy (mp->reid, reid_mac, 6);
17200       break;
17201     default:
17202       errmsg ("unknown EID type %d!", mp->eid_type);
17203       return 0;
17204     }
17205
17206   /* send it... */
17207   S (mp);
17208
17209   /* Wait for a reply... */
17210   W (ret);
17211   return ret;
17212 }
17213
17214 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17215
17216 uword
17217 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17218 {
17219   u32 *mode = va_arg (*args, u32 *);
17220
17221   if (unformat (input, "lisp"))
17222     *mode = 0;
17223   else if (unformat (input, "vxlan"))
17224     *mode = 1;
17225   else
17226     return 0;
17227
17228   return 1;
17229 }
17230
17231 static int
17232 api_gpe_get_encap_mode (vat_main_t * vam)
17233 {
17234   vl_api_gpe_get_encap_mode_t *mp;
17235   int ret;
17236
17237   /* Construct the API message */
17238   M (GPE_GET_ENCAP_MODE, mp);
17239
17240   /* send it... */
17241   S (mp);
17242
17243   /* Wait for a reply... */
17244   W (ret);
17245   return ret;
17246 }
17247
17248 static int
17249 api_gpe_set_encap_mode (vat_main_t * vam)
17250 {
17251   unformat_input_t *input = vam->input;
17252   vl_api_gpe_set_encap_mode_t *mp;
17253   int ret;
17254   u32 mode = 0;
17255
17256   /* Parse args required to build the message */
17257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17260         ;
17261       else
17262         break;
17263     }
17264
17265   /* Construct the API message */
17266   M (GPE_SET_ENCAP_MODE, mp);
17267
17268   mp->mode = mode;
17269
17270   /* send it... */
17271   S (mp);
17272
17273   /* Wait for a reply... */
17274   W (ret);
17275   return ret;
17276 }
17277
17278 static int
17279 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17280 {
17281   unformat_input_t *input = vam->input;
17282   vl_api_gpe_add_del_iface_t *mp;
17283   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17284   u32 dp_table = 0, vni = 0;
17285   int ret;
17286
17287   /* Parse args required to build the message */
17288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17289     {
17290       if (unformat (input, "up"))
17291         {
17292           action_set = 1;
17293           is_add = 1;
17294         }
17295       else if (unformat (input, "down"))
17296         {
17297           action_set = 1;
17298           is_add = 0;
17299         }
17300       else if (unformat (input, "table_id %d", &dp_table))
17301         {
17302           dp_table_set = 1;
17303         }
17304       else if (unformat (input, "bd_id %d", &dp_table))
17305         {
17306           dp_table_set = 1;
17307           is_l2 = 1;
17308         }
17309       else if (unformat (input, "vni %d", &vni))
17310         {
17311           vni_set = 1;
17312         }
17313       else
17314         break;
17315     }
17316
17317   if (action_set == 0)
17318     {
17319       errmsg ("Action not set");
17320       return -99;
17321     }
17322   if (dp_table_set == 0 || vni_set == 0)
17323     {
17324       errmsg ("vni and dp_table must be set");
17325       return -99;
17326     }
17327
17328   /* Construct the API message */
17329   M (GPE_ADD_DEL_IFACE, mp);
17330
17331   mp->is_add = is_add;
17332   mp->dp_table = clib_host_to_net_u32 (dp_table);
17333   mp->is_l2 = is_l2;
17334   mp->vni = clib_host_to_net_u32 (vni);
17335
17336   /* send it... */
17337   S (mp);
17338
17339   /* Wait for a reply... */
17340   W (ret);
17341   return ret;
17342 }
17343
17344 static int
17345 api_one_map_register_fallback_threshold (vat_main_t * vam)
17346 {
17347   unformat_input_t *input = vam->input;
17348   vl_api_one_map_register_fallback_threshold_t *mp;
17349   u32 value = 0;
17350   u8 is_set = 0;
17351   int ret;
17352
17353   /* Parse args required to build the message */
17354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17355     {
17356       if (unformat (input, "%u", &value))
17357         is_set = 1;
17358       else
17359         {
17360           clib_warning ("parse error '%U'", format_unformat_error, input);
17361           return -99;
17362         }
17363     }
17364
17365   if (!is_set)
17366     {
17367       errmsg ("fallback threshold value is missing!");
17368       return -99;
17369     }
17370
17371   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17372   mp->value = clib_host_to_net_u32 (value);
17373
17374   /* send it... */
17375   S (mp);
17376
17377   /* Wait for a reply... */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 static int
17383 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17384 {
17385   vl_api_show_one_map_register_fallback_threshold_t *mp;
17386   int ret;
17387
17388   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17389
17390   /* send it... */
17391   S (mp);
17392
17393   /* Wait for a reply... */
17394   W (ret);
17395   return ret;
17396 }
17397
17398 uword
17399 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17400 {
17401   u32 *proto = va_arg (*args, u32 *);
17402
17403   if (unformat (input, "udp"))
17404     *proto = 1;
17405   else if (unformat (input, "api"))
17406     *proto = 2;
17407   else
17408     return 0;
17409
17410   return 1;
17411 }
17412
17413 static int
17414 api_one_set_transport_protocol (vat_main_t * vam)
17415 {
17416   unformat_input_t *input = vam->input;
17417   vl_api_one_set_transport_protocol_t *mp;
17418   u8 is_set = 0;
17419   u32 protocol = 0;
17420   int ret;
17421
17422   /* Parse args required to build the message */
17423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17424     {
17425       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17426         is_set = 1;
17427       else
17428         {
17429           clib_warning ("parse error '%U'", format_unformat_error, input);
17430           return -99;
17431         }
17432     }
17433
17434   if (!is_set)
17435     {
17436       errmsg ("Transport protocol missing!");
17437       return -99;
17438     }
17439
17440   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17441   mp->protocol = (u8) protocol;
17442
17443   /* send it... */
17444   S (mp);
17445
17446   /* Wait for a reply... */
17447   W (ret);
17448   return ret;
17449 }
17450
17451 static int
17452 api_one_get_transport_protocol (vat_main_t * vam)
17453 {
17454   vl_api_one_get_transport_protocol_t *mp;
17455   int ret;
17456
17457   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17458
17459   /* send it... */
17460   S (mp);
17461
17462   /* Wait for a reply... */
17463   W (ret);
17464   return ret;
17465 }
17466
17467 static int
17468 api_one_map_register_set_ttl (vat_main_t * vam)
17469 {
17470   unformat_input_t *input = vam->input;
17471   vl_api_one_map_register_set_ttl_t *mp;
17472   u32 ttl = 0;
17473   u8 is_set = 0;
17474   int ret;
17475
17476   /* Parse args required to build the message */
17477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17478     {
17479       if (unformat (input, "%u", &ttl))
17480         is_set = 1;
17481       else
17482         {
17483           clib_warning ("parse error '%U'", format_unformat_error, input);
17484           return -99;
17485         }
17486     }
17487
17488   if (!is_set)
17489     {
17490       errmsg ("TTL value missing!");
17491       return -99;
17492     }
17493
17494   M (ONE_MAP_REGISTER_SET_TTL, mp);
17495   mp->ttl = clib_host_to_net_u32 (ttl);
17496
17497   /* send it... */
17498   S (mp);
17499
17500   /* Wait for a reply... */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 static int
17506 api_show_one_map_register_ttl (vat_main_t * vam)
17507 {
17508   vl_api_show_one_map_register_ttl_t *mp;
17509   int ret;
17510
17511   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17512
17513   /* send it... */
17514   S (mp);
17515
17516   /* Wait for a reply... */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 /**
17522  * Add/del map request itr rlocs from ONE control plane and updates
17523  *
17524  * @param vam vpp API test context
17525  * @return return code
17526  */
17527 static int
17528 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17529 {
17530   unformat_input_t *input = vam->input;
17531   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17532   u8 *locator_set_name = 0;
17533   u8 locator_set_name_set = 0;
17534   u8 is_add = 1;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "del"))
17541         {
17542           is_add = 0;
17543         }
17544       else if (unformat (input, "%_%v%_", &locator_set_name))
17545         {
17546           locator_set_name_set = 1;
17547         }
17548       else
17549         {
17550           clib_warning ("parse error '%U'", format_unformat_error, input);
17551           return -99;
17552         }
17553     }
17554
17555   if (is_add && !locator_set_name_set)
17556     {
17557       errmsg ("itr-rloc is not set!");
17558       return -99;
17559     }
17560
17561   if (is_add && vec_len (locator_set_name) > 64)
17562     {
17563       errmsg ("itr-rloc locator-set name too long");
17564       vec_free (locator_set_name);
17565       return -99;
17566     }
17567
17568   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17569   mp->is_add = is_add;
17570   if (is_add)
17571     {
17572       clib_memcpy (mp->locator_set_name, locator_set_name,
17573                    vec_len (locator_set_name));
17574     }
17575   else
17576     {
17577       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17578     }
17579   vec_free (locator_set_name);
17580
17581   /* send it... */
17582   S (mp);
17583
17584   /* Wait for a reply... */
17585   W (ret);
17586   return ret;
17587 }
17588
17589 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17590
17591 static int
17592 api_one_locator_dump (vat_main_t * vam)
17593 {
17594   unformat_input_t *input = vam->input;
17595   vl_api_one_locator_dump_t *mp;
17596   vl_api_control_ping_t *mp_ping;
17597   u8 is_index_set = 0, is_name_set = 0;
17598   u8 *ls_name = 0;
17599   u32 ls_index = ~0;
17600   int ret;
17601
17602   /* Parse args required to build the message */
17603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17604     {
17605       if (unformat (input, "ls_name %_%v%_", &ls_name))
17606         {
17607           is_name_set = 1;
17608         }
17609       else if (unformat (input, "ls_index %d", &ls_index))
17610         {
17611           is_index_set = 1;
17612         }
17613       else
17614         {
17615           errmsg ("parse error '%U'", format_unformat_error, input);
17616           return -99;
17617         }
17618     }
17619
17620   if (!is_index_set && !is_name_set)
17621     {
17622       errmsg ("error: expected one of index or name!");
17623       return -99;
17624     }
17625
17626   if (is_index_set && is_name_set)
17627     {
17628       errmsg ("error: only one param expected!");
17629       return -99;
17630     }
17631
17632   if (vec_len (ls_name) > 62)
17633     {
17634       errmsg ("error: locator set name too long!");
17635       return -99;
17636     }
17637
17638   if (!vam->json_output)
17639     {
17640       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17641     }
17642
17643   M (ONE_LOCATOR_DUMP, mp);
17644   mp->is_index_set = is_index_set;
17645
17646   if (is_index_set)
17647     mp->ls_index = clib_host_to_net_u32 (ls_index);
17648   else
17649     {
17650       vec_add1 (ls_name, 0);
17651       strncpy ((char *) mp->ls_name, (char *) ls_name,
17652                sizeof (mp->ls_name) - 1);
17653     }
17654
17655   /* send it... */
17656   S (mp);
17657
17658   /* Use a control ping for synchronization */
17659   MPING (CONTROL_PING, mp_ping);
17660   S (mp_ping);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 #define api_lisp_locator_dump api_one_locator_dump
17668
17669 static int
17670 api_one_locator_set_dump (vat_main_t * vam)
17671 {
17672   vl_api_one_locator_set_dump_t *mp;
17673   vl_api_control_ping_t *mp_ping;
17674   unformat_input_t *input = vam->input;
17675   u8 filter = 0;
17676   int ret;
17677
17678   /* Parse args required to build the message */
17679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17680     {
17681       if (unformat (input, "local"))
17682         {
17683           filter = 1;
17684         }
17685       else if (unformat (input, "remote"))
17686         {
17687           filter = 2;
17688         }
17689       else
17690         {
17691           errmsg ("parse error '%U'", format_unformat_error, input);
17692           return -99;
17693         }
17694     }
17695
17696   if (!vam->json_output)
17697     {
17698       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17699     }
17700
17701   M (ONE_LOCATOR_SET_DUMP, mp);
17702
17703   mp->filter = filter;
17704
17705   /* send it... */
17706   S (mp);
17707
17708   /* Use a control ping for synchronization */
17709   MPING (CONTROL_PING, mp_ping);
17710   S (mp_ping);
17711
17712   /* Wait for a reply... */
17713   W (ret);
17714   return ret;
17715 }
17716
17717 #define api_lisp_locator_set_dump api_one_locator_set_dump
17718
17719 static int
17720 api_one_eid_table_map_dump (vat_main_t * vam)
17721 {
17722   u8 is_l2 = 0;
17723   u8 mode_set = 0;
17724   unformat_input_t *input = vam->input;
17725   vl_api_one_eid_table_map_dump_t *mp;
17726   vl_api_control_ping_t *mp_ping;
17727   int ret;
17728
17729   /* Parse args required to build the message */
17730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17731     {
17732       if (unformat (input, "l2"))
17733         {
17734           is_l2 = 1;
17735           mode_set = 1;
17736         }
17737       else if (unformat (input, "l3"))
17738         {
17739           is_l2 = 0;
17740           mode_set = 1;
17741         }
17742       else
17743         {
17744           errmsg ("parse error '%U'", format_unformat_error, input);
17745           return -99;
17746         }
17747     }
17748
17749   if (!mode_set)
17750     {
17751       errmsg ("expected one of 'l2' or 'l3' parameter!");
17752       return -99;
17753     }
17754
17755   if (!vam->json_output)
17756     {
17757       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17758     }
17759
17760   M (ONE_EID_TABLE_MAP_DUMP, mp);
17761   mp->is_l2 = is_l2;
17762
17763   /* send it... */
17764   S (mp);
17765
17766   /* Use a control ping for synchronization */
17767   MPING (CONTROL_PING, mp_ping);
17768   S (mp_ping);
17769
17770   /* Wait for a reply... */
17771   W (ret);
17772   return ret;
17773 }
17774
17775 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17776
17777 static int
17778 api_one_eid_table_vni_dump (vat_main_t * vam)
17779 {
17780   vl_api_one_eid_table_vni_dump_t *mp;
17781   vl_api_control_ping_t *mp_ping;
17782   int ret;
17783
17784   if (!vam->json_output)
17785     {
17786       print (vam->ofp, "VNI");
17787     }
17788
17789   M (ONE_EID_TABLE_VNI_DUMP, mp);
17790
17791   /* send it... */
17792   S (mp);
17793
17794   /* Use a control ping for synchronization */
17795   MPING (CONTROL_PING, mp_ping);
17796   S (mp_ping);
17797
17798   /* Wait for a reply... */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17804
17805 static int
17806 api_one_eid_table_dump (vat_main_t * vam)
17807 {
17808   unformat_input_t *i = vam->input;
17809   vl_api_one_eid_table_dump_t *mp;
17810   vl_api_control_ping_t *mp_ping;
17811   struct in_addr ip4;
17812   struct in6_addr ip6;
17813   u8 mac[6];
17814   u8 eid_type = ~0, eid_set = 0;
17815   u32 prefix_length = ~0, t, vni = 0;
17816   u8 filter = 0;
17817   int ret;
17818   lisp_nsh_api_t nsh;
17819
17820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17821     {
17822       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17823         {
17824           eid_set = 1;
17825           eid_type = 0;
17826           prefix_length = t;
17827         }
17828       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17829         {
17830           eid_set = 1;
17831           eid_type = 1;
17832           prefix_length = t;
17833         }
17834       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17835         {
17836           eid_set = 1;
17837           eid_type = 2;
17838         }
17839       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17840         {
17841           eid_set = 1;
17842           eid_type = 3;
17843         }
17844       else if (unformat (i, "vni %d", &t))
17845         {
17846           vni = t;
17847         }
17848       else if (unformat (i, "local"))
17849         {
17850           filter = 1;
17851         }
17852       else if (unformat (i, "remote"))
17853         {
17854           filter = 2;
17855         }
17856       else
17857         {
17858           errmsg ("parse error '%U'", format_unformat_error, i);
17859           return -99;
17860         }
17861     }
17862
17863   if (!vam->json_output)
17864     {
17865       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17866              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17867     }
17868
17869   M (ONE_EID_TABLE_DUMP, mp);
17870
17871   mp->filter = filter;
17872   if (eid_set)
17873     {
17874       mp->eid_set = 1;
17875       mp->vni = htonl (vni);
17876       mp->eid_type = eid_type;
17877       switch (eid_type)
17878         {
17879         case 0:
17880           mp->prefix_length = prefix_length;
17881           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17882           break;
17883         case 1:
17884           mp->prefix_length = prefix_length;
17885           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17886           break;
17887         case 2:
17888           clib_memcpy (mp->eid, mac, sizeof (mac));
17889           break;
17890         case 3:
17891           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17892           break;
17893         default:
17894           errmsg ("unknown EID type %d!", eid_type);
17895           return -99;
17896         }
17897     }
17898
17899   /* send it... */
17900   S (mp);
17901
17902   /* Use a control ping for synchronization */
17903   MPING (CONTROL_PING, mp_ping);
17904   S (mp_ping);
17905
17906   /* Wait for a reply... */
17907   W (ret);
17908   return ret;
17909 }
17910
17911 #define api_lisp_eid_table_dump api_one_eid_table_dump
17912
17913 static int
17914 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17915 {
17916   unformat_input_t *i = vam->input;
17917   vl_api_gpe_fwd_entries_get_t *mp;
17918   u8 vni_set = 0;
17919   u32 vni = ~0;
17920   int ret;
17921
17922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17923     {
17924       if (unformat (i, "vni %d", &vni))
17925         {
17926           vni_set = 1;
17927         }
17928       else
17929         {
17930           errmsg ("parse error '%U'", format_unformat_error, i);
17931           return -99;
17932         }
17933     }
17934
17935   if (!vni_set)
17936     {
17937       errmsg ("vni not set!");
17938       return -99;
17939     }
17940
17941   if (!vam->json_output)
17942     {
17943       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17944              "leid", "reid");
17945     }
17946
17947   M (GPE_FWD_ENTRIES_GET, mp);
17948   mp->vni = clib_host_to_net_u32 (vni);
17949
17950   /* send it... */
17951   S (mp);
17952
17953   /* Wait for a reply... */
17954   W (ret);
17955   return ret;
17956 }
17957
17958 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17959 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17960 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17961 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17962 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17963 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17964 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17965 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17966
17967 static int
17968 api_one_adjacencies_get (vat_main_t * vam)
17969 {
17970   unformat_input_t *i = vam->input;
17971   vl_api_one_adjacencies_get_t *mp;
17972   u8 vni_set = 0;
17973   u32 vni = ~0;
17974   int ret;
17975
17976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17977     {
17978       if (unformat (i, "vni %d", &vni))
17979         {
17980           vni_set = 1;
17981         }
17982       else
17983         {
17984           errmsg ("parse error '%U'", format_unformat_error, i);
17985           return -99;
17986         }
17987     }
17988
17989   if (!vni_set)
17990     {
17991       errmsg ("vni not set!");
17992       return -99;
17993     }
17994
17995   if (!vam->json_output)
17996     {
17997       print (vam->ofp, "%s %40s", "leid", "reid");
17998     }
17999
18000   M (ONE_ADJACENCIES_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 api_lisp_adjacencies_get api_one_adjacencies_get
18012
18013 static int
18014 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18015 {
18016   unformat_input_t *i = vam->input;
18017   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18018   int ret;
18019   u8 ip_family_set = 0, is_ip4 = 1;
18020
18021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18022     {
18023       if (unformat (i, "ip4"))
18024         {
18025           ip_family_set = 1;
18026           is_ip4 = 1;
18027         }
18028       else if (unformat (i, "ip6"))
18029         {
18030           ip_family_set = 1;
18031           is_ip4 = 0;
18032         }
18033       else
18034         {
18035           errmsg ("parse error '%U'", format_unformat_error, i);
18036           return -99;
18037         }
18038     }
18039
18040   if (!ip_family_set)
18041     {
18042       errmsg ("ip family not set!");
18043       return -99;
18044     }
18045
18046   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18047   mp->is_ip4 = is_ip4;
18048
18049   /* send it... */
18050   S (mp);
18051
18052   /* Wait for a reply... */
18053   W (ret);
18054   return ret;
18055 }
18056
18057 static int
18058 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18059 {
18060   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18061   int ret;
18062
18063   if (!vam->json_output)
18064     {
18065       print (vam->ofp, "VNIs");
18066     }
18067
18068   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18069
18070   /* send it... */
18071   S (mp);
18072
18073   /* Wait for a reply... */
18074   W (ret);
18075   return ret;
18076 }
18077
18078 static int
18079 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18080 {
18081   unformat_input_t *i = vam->input;
18082   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18083   int ret = 0;
18084   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18085   struct in_addr ip4;
18086   struct in6_addr ip6;
18087   u32 table_id = 0, nh_sw_if_index = ~0;
18088
18089   memset (&ip4, 0, sizeof (ip4));
18090   memset (&ip6, 0, sizeof (ip6));
18091
18092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18093     {
18094       if (unformat (i, "del"))
18095         is_add = 0;
18096       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18097                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18098         {
18099           ip_set = 1;
18100           is_ip4 = 1;
18101         }
18102       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18103                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18104         {
18105           ip_set = 1;
18106           is_ip4 = 0;
18107         }
18108       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18109         {
18110           ip_set = 1;
18111           is_ip4 = 1;
18112           nh_sw_if_index = ~0;
18113         }
18114       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18115         {
18116           ip_set = 1;
18117           is_ip4 = 0;
18118           nh_sw_if_index = ~0;
18119         }
18120       else if (unformat (i, "table %d", &table_id))
18121         ;
18122       else
18123         {
18124           errmsg ("parse error '%U'", format_unformat_error, i);
18125           return -99;
18126         }
18127     }
18128
18129   if (!ip_set)
18130     {
18131       errmsg ("nh addr not set!");
18132       return -99;
18133     }
18134
18135   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18136   mp->is_add = is_add;
18137   mp->table_id = clib_host_to_net_u32 (table_id);
18138   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18139   mp->is_ip4 = is_ip4;
18140   if (is_ip4)
18141     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18142   else
18143     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18144
18145   /* send it... */
18146   S (mp);
18147
18148   /* Wait for a reply... */
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static int
18154 api_one_map_server_dump (vat_main_t * vam)
18155 {
18156   vl_api_one_map_server_dump_t *mp;
18157   vl_api_control_ping_t *mp_ping;
18158   int ret;
18159
18160   if (!vam->json_output)
18161     {
18162       print (vam->ofp, "%=20s", "Map server");
18163     }
18164
18165   M (ONE_MAP_SERVER_DUMP, mp);
18166   /* send it... */
18167   S (mp);
18168
18169   /* Use a control ping for synchronization */
18170   MPING (CONTROL_PING, mp_ping);
18171   S (mp_ping);
18172
18173   /* Wait for a reply... */
18174   W (ret);
18175   return ret;
18176 }
18177
18178 #define api_lisp_map_server_dump api_one_map_server_dump
18179
18180 static int
18181 api_one_map_resolver_dump (vat_main_t * vam)
18182 {
18183   vl_api_one_map_resolver_dump_t *mp;
18184   vl_api_control_ping_t *mp_ping;
18185   int ret;
18186
18187   if (!vam->json_output)
18188     {
18189       print (vam->ofp, "%=20s", "Map resolver");
18190     }
18191
18192   M (ONE_MAP_RESOLVER_DUMP, mp);
18193   /* send it... */
18194   S (mp);
18195
18196   /* Use a control ping for synchronization */
18197   MPING (CONTROL_PING, mp_ping);
18198   S (mp_ping);
18199
18200   /* Wait for a reply... */
18201   W (ret);
18202   return ret;
18203 }
18204
18205 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18206
18207 static int
18208 api_one_stats_flush (vat_main_t * vam)
18209 {
18210   vl_api_one_stats_flush_t *mp;
18211   int ret = 0;
18212
18213   M (ONE_STATS_FLUSH, mp);
18214   S (mp);
18215   W (ret);
18216   return ret;
18217 }
18218
18219 static int
18220 api_one_stats_dump (vat_main_t * vam)
18221 {
18222   vl_api_one_stats_dump_t *mp;
18223   vl_api_control_ping_t *mp_ping;
18224   int ret;
18225
18226   M (ONE_STATS_DUMP, mp);
18227   /* send it... */
18228   S (mp);
18229
18230   /* Use a control ping for synchronization */
18231   MPING (CONTROL_PING, mp_ping);
18232   S (mp_ping);
18233
18234   /* Wait for a reply... */
18235   W (ret);
18236   return ret;
18237 }
18238
18239 static int
18240 api_show_one_status (vat_main_t * vam)
18241 {
18242   vl_api_show_one_status_t *mp;
18243   int ret;
18244
18245   if (!vam->json_output)
18246     {
18247       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18248     }
18249
18250   M (SHOW_ONE_STATUS, mp);
18251   /* send it... */
18252   S (mp);
18253   /* Wait for a reply... */
18254   W (ret);
18255   return ret;
18256 }
18257
18258 #define api_show_lisp_status api_show_one_status
18259
18260 static int
18261 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18262 {
18263   vl_api_gpe_fwd_entry_path_dump_t *mp;
18264   vl_api_control_ping_t *mp_ping;
18265   unformat_input_t *i = vam->input;
18266   u32 fwd_entry_index = ~0;
18267   int ret;
18268
18269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18270     {
18271       if (unformat (i, "index %d", &fwd_entry_index))
18272         ;
18273       else
18274         break;
18275     }
18276
18277   if (~0 == fwd_entry_index)
18278     {
18279       errmsg ("no index specified!");
18280       return -99;
18281     }
18282
18283   if (!vam->json_output)
18284     {
18285       print (vam->ofp, "first line");
18286     }
18287
18288   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18289
18290   /* send it... */
18291   S (mp);
18292   /* Use a control ping for synchronization */
18293   MPING (CONTROL_PING, mp_ping);
18294   S (mp_ping);
18295
18296   /* Wait for a reply... */
18297   W (ret);
18298   return ret;
18299 }
18300
18301 static int
18302 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18303 {
18304   vl_api_one_get_map_request_itr_rlocs_t *mp;
18305   int ret;
18306
18307   if (!vam->json_output)
18308     {
18309       print (vam->ofp, "%=20s", "itr-rlocs:");
18310     }
18311
18312   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18313   /* send it... */
18314   S (mp);
18315   /* Wait for a reply... */
18316   W (ret);
18317   return ret;
18318 }
18319
18320 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18321
18322 static int
18323 api_af_packet_create (vat_main_t * vam)
18324 {
18325   unformat_input_t *i = vam->input;
18326   vl_api_af_packet_create_t *mp;
18327   u8 *host_if_name = 0;
18328   u8 hw_addr[6];
18329   u8 random_hw_addr = 1;
18330   int ret;
18331
18332   memset (hw_addr, 0, sizeof (hw_addr));
18333
18334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18335     {
18336       if (unformat (i, "name %s", &host_if_name))
18337         vec_add1 (host_if_name, 0);
18338       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18339         random_hw_addr = 0;
18340       else
18341         break;
18342     }
18343
18344   if (!vec_len (host_if_name))
18345     {
18346       errmsg ("host-interface name must be specified");
18347       return -99;
18348     }
18349
18350   if (vec_len (host_if_name) > 64)
18351     {
18352       errmsg ("host-interface name too long");
18353       return -99;
18354     }
18355
18356   M (AF_PACKET_CREATE, mp);
18357
18358   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18359   clib_memcpy (mp->hw_addr, hw_addr, 6);
18360   mp->use_random_hw_addr = random_hw_addr;
18361   vec_free (host_if_name);
18362
18363   S (mp);
18364
18365   /* *INDENT-OFF* */
18366   W2 (ret,
18367       ({
18368         if (ret == 0)
18369           fprintf (vam->ofp ? vam->ofp : stderr,
18370                    " new sw_if_index = %d\n", vam->sw_if_index);
18371       }));
18372   /* *INDENT-ON* */
18373   return ret;
18374 }
18375
18376 static int
18377 api_af_packet_delete (vat_main_t * vam)
18378 {
18379   unformat_input_t *i = vam->input;
18380   vl_api_af_packet_delete_t *mp;
18381   u8 *host_if_name = 0;
18382   int ret;
18383
18384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18385     {
18386       if (unformat (i, "name %s", &host_if_name))
18387         vec_add1 (host_if_name, 0);
18388       else
18389         break;
18390     }
18391
18392   if (!vec_len (host_if_name))
18393     {
18394       errmsg ("host-interface name must be specified");
18395       return -99;
18396     }
18397
18398   if (vec_len (host_if_name) > 64)
18399     {
18400       errmsg ("host-interface name too long");
18401       return -99;
18402     }
18403
18404   M (AF_PACKET_DELETE, mp);
18405
18406   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18407   vec_free (host_if_name);
18408
18409   S (mp);
18410   W (ret);
18411   return ret;
18412 }
18413
18414 static int
18415 api_policer_add_del (vat_main_t * vam)
18416 {
18417   unformat_input_t *i = vam->input;
18418   vl_api_policer_add_del_t *mp;
18419   u8 is_add = 1;
18420   u8 *name = 0;
18421   u32 cir = 0;
18422   u32 eir = 0;
18423   u64 cb = 0;
18424   u64 eb = 0;
18425   u8 rate_type = 0;
18426   u8 round_type = 0;
18427   u8 type = 0;
18428   u8 color_aware = 0;
18429   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18430   int ret;
18431
18432   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18433   conform_action.dscp = 0;
18434   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18435   exceed_action.dscp = 0;
18436   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18437   violate_action.dscp = 0;
18438
18439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18440     {
18441       if (unformat (i, "del"))
18442         is_add = 0;
18443       else if (unformat (i, "name %s", &name))
18444         vec_add1 (name, 0);
18445       else if (unformat (i, "cir %u", &cir))
18446         ;
18447       else if (unformat (i, "eir %u", &eir))
18448         ;
18449       else if (unformat (i, "cb %u", &cb))
18450         ;
18451       else if (unformat (i, "eb %u", &eb))
18452         ;
18453       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18454                          &rate_type))
18455         ;
18456       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18457                          &round_type))
18458         ;
18459       else if (unformat (i, "type %U", unformat_policer_type, &type))
18460         ;
18461       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18462                          &conform_action))
18463         ;
18464       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18465                          &exceed_action))
18466         ;
18467       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18468                          &violate_action))
18469         ;
18470       else if (unformat (i, "color-aware"))
18471         color_aware = 1;
18472       else
18473         break;
18474     }
18475
18476   if (!vec_len (name))
18477     {
18478       errmsg ("policer name must be specified");
18479       return -99;
18480     }
18481
18482   if (vec_len (name) > 64)
18483     {
18484       errmsg ("policer name too long");
18485       return -99;
18486     }
18487
18488   M (POLICER_ADD_DEL, mp);
18489
18490   clib_memcpy (mp->name, name, vec_len (name));
18491   vec_free (name);
18492   mp->is_add = is_add;
18493   mp->cir = ntohl (cir);
18494   mp->eir = ntohl (eir);
18495   mp->cb = clib_net_to_host_u64 (cb);
18496   mp->eb = clib_net_to_host_u64 (eb);
18497   mp->rate_type = rate_type;
18498   mp->round_type = round_type;
18499   mp->type = type;
18500   mp->conform_action_type = conform_action.action_type;
18501   mp->conform_dscp = conform_action.dscp;
18502   mp->exceed_action_type = exceed_action.action_type;
18503   mp->exceed_dscp = exceed_action.dscp;
18504   mp->violate_action_type = violate_action.action_type;
18505   mp->violate_dscp = violate_action.dscp;
18506   mp->color_aware = color_aware;
18507
18508   S (mp);
18509   W (ret);
18510   return ret;
18511 }
18512
18513 static int
18514 api_policer_dump (vat_main_t * vam)
18515 {
18516   unformat_input_t *i = vam->input;
18517   vl_api_policer_dump_t *mp;
18518   vl_api_control_ping_t *mp_ping;
18519   u8 *match_name = 0;
18520   u8 match_name_valid = 0;
18521   int ret;
18522
18523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18524     {
18525       if (unformat (i, "name %s", &match_name))
18526         {
18527           vec_add1 (match_name, 0);
18528           match_name_valid = 1;
18529         }
18530       else
18531         break;
18532     }
18533
18534   M (POLICER_DUMP, mp);
18535   mp->match_name_valid = match_name_valid;
18536   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18537   vec_free (match_name);
18538   /* send it... */
18539   S (mp);
18540
18541   /* Use a control ping for synchronization */
18542   MPING (CONTROL_PING, mp_ping);
18543   S (mp_ping);
18544
18545   /* Wait for a reply... */
18546   W (ret);
18547   return ret;
18548 }
18549
18550 static int
18551 api_policer_classify_set_interface (vat_main_t * vam)
18552 {
18553   unformat_input_t *i = vam->input;
18554   vl_api_policer_classify_set_interface_t *mp;
18555   u32 sw_if_index;
18556   int sw_if_index_set;
18557   u32 ip4_table_index = ~0;
18558   u32 ip6_table_index = ~0;
18559   u32 l2_table_index = ~0;
18560   u8 is_add = 1;
18561   int ret;
18562
18563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18564     {
18565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18566         sw_if_index_set = 1;
18567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18568         sw_if_index_set = 1;
18569       else if (unformat (i, "del"))
18570         is_add = 0;
18571       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18572         ;
18573       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18574         ;
18575       else if (unformat (i, "l2-table %d", &l2_table_index))
18576         ;
18577       else
18578         {
18579           clib_warning ("parse error '%U'", format_unformat_error, i);
18580           return -99;
18581         }
18582     }
18583
18584   if (sw_if_index_set == 0)
18585     {
18586       errmsg ("missing interface name or sw_if_index");
18587       return -99;
18588     }
18589
18590   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18591
18592   mp->sw_if_index = ntohl (sw_if_index);
18593   mp->ip4_table_index = ntohl (ip4_table_index);
18594   mp->ip6_table_index = ntohl (ip6_table_index);
18595   mp->l2_table_index = ntohl (l2_table_index);
18596   mp->is_add = is_add;
18597
18598   S (mp);
18599   W (ret);
18600   return ret;
18601 }
18602
18603 static int
18604 api_policer_classify_dump (vat_main_t * vam)
18605 {
18606   unformat_input_t *i = vam->input;
18607   vl_api_policer_classify_dump_t *mp;
18608   vl_api_control_ping_t *mp_ping;
18609   u8 type = POLICER_CLASSIFY_N_TABLES;
18610   int ret;
18611
18612   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18613     ;
18614   else
18615     {
18616       errmsg ("classify table type must be specified");
18617       return -99;
18618     }
18619
18620   if (!vam->json_output)
18621     {
18622       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18623     }
18624
18625   M (POLICER_CLASSIFY_DUMP, mp);
18626   mp->type = type;
18627   /* send it... */
18628   S (mp);
18629
18630   /* Use a control ping for synchronization */
18631   MPING (CONTROL_PING, mp_ping);
18632   S (mp_ping);
18633
18634   /* Wait for a reply... */
18635   W (ret);
18636   return ret;
18637 }
18638
18639 static int
18640 api_netmap_create (vat_main_t * vam)
18641 {
18642   unformat_input_t *i = vam->input;
18643   vl_api_netmap_create_t *mp;
18644   u8 *if_name = 0;
18645   u8 hw_addr[6];
18646   u8 random_hw_addr = 1;
18647   u8 is_pipe = 0;
18648   u8 is_master = 0;
18649   int ret;
18650
18651   memset (hw_addr, 0, sizeof (hw_addr));
18652
18653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18654     {
18655       if (unformat (i, "name %s", &if_name))
18656         vec_add1 (if_name, 0);
18657       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18658         random_hw_addr = 0;
18659       else if (unformat (i, "pipe"))
18660         is_pipe = 1;
18661       else if (unformat (i, "master"))
18662         is_master = 1;
18663       else if (unformat (i, "slave"))
18664         is_master = 0;
18665       else
18666         break;
18667     }
18668
18669   if (!vec_len (if_name))
18670     {
18671       errmsg ("interface name must be specified");
18672       return -99;
18673     }
18674
18675   if (vec_len (if_name) > 64)
18676     {
18677       errmsg ("interface name too long");
18678       return -99;
18679     }
18680
18681   M (NETMAP_CREATE, mp);
18682
18683   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18684   clib_memcpy (mp->hw_addr, hw_addr, 6);
18685   mp->use_random_hw_addr = random_hw_addr;
18686   mp->is_pipe = is_pipe;
18687   mp->is_master = is_master;
18688   vec_free (if_name);
18689
18690   S (mp);
18691   W (ret);
18692   return ret;
18693 }
18694
18695 static int
18696 api_netmap_delete (vat_main_t * vam)
18697 {
18698   unformat_input_t *i = vam->input;
18699   vl_api_netmap_delete_t *mp;
18700   u8 *if_name = 0;
18701   int ret;
18702
18703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18704     {
18705       if (unformat (i, "name %s", &if_name))
18706         vec_add1 (if_name, 0);
18707       else
18708         break;
18709     }
18710
18711   if (!vec_len (if_name))
18712     {
18713       errmsg ("interface name must be specified");
18714       return -99;
18715     }
18716
18717   if (vec_len (if_name) > 64)
18718     {
18719       errmsg ("interface name too long");
18720       return -99;
18721     }
18722
18723   M (NETMAP_DELETE, mp);
18724
18725   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18726   vec_free (if_name);
18727
18728   S (mp);
18729   W (ret);
18730   return ret;
18731 }
18732
18733 static void
18734 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18735 {
18736   if (fp->afi == IP46_TYPE_IP6)
18737     print (vam->ofp,
18738            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18739            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18740            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18741            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18742            format_ip6_address, fp->next_hop);
18743   else if (fp->afi == IP46_TYPE_IP4)
18744     print (vam->ofp,
18745            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18746            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18747            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18748            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18749            format_ip4_address, fp->next_hop);
18750 }
18751
18752 static void
18753 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18754                                  vl_api_fib_path2_t * fp)
18755 {
18756   struct in_addr ip4;
18757   struct in6_addr ip6;
18758
18759   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18760   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18761   vat_json_object_add_uint (node, "is_local", fp->is_local);
18762   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18763   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18764   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18765   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18766   if (fp->afi == IP46_TYPE_IP4)
18767     {
18768       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18769       vat_json_object_add_ip4 (node, "next_hop", ip4);
18770     }
18771   else if (fp->afi == IP46_TYPE_IP6)
18772     {
18773       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18774       vat_json_object_add_ip6 (node, "next_hop", ip6);
18775     }
18776 }
18777
18778 static void
18779 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18780 {
18781   vat_main_t *vam = &vat_main;
18782   int count = ntohl (mp->mt_count);
18783   vl_api_fib_path2_t *fp;
18784   i32 i;
18785
18786   print (vam->ofp, "[%d]: sw_if_index %d via:",
18787          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18788   fp = mp->mt_paths;
18789   for (i = 0; i < count; i++)
18790     {
18791       vl_api_mpls_fib_path_print (vam, fp);
18792       fp++;
18793     }
18794
18795   print (vam->ofp, "");
18796 }
18797
18798 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18799 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18800
18801 static void
18802 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18803 {
18804   vat_main_t *vam = &vat_main;
18805   vat_json_node_t *node = NULL;
18806   int count = ntohl (mp->mt_count);
18807   vl_api_fib_path2_t *fp;
18808   i32 i;
18809
18810   if (VAT_JSON_ARRAY != vam->json_tree.type)
18811     {
18812       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18813       vat_json_init_array (&vam->json_tree);
18814     }
18815   node = vat_json_array_add (&vam->json_tree);
18816
18817   vat_json_init_object (node);
18818   vat_json_object_add_uint (node, "tunnel_index",
18819                             ntohl (mp->mt_tunnel_index));
18820   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18821
18822   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18823
18824   fp = mp->mt_paths;
18825   for (i = 0; i < count; i++)
18826     {
18827       vl_api_mpls_fib_path_json_print (node, fp);
18828       fp++;
18829     }
18830 }
18831
18832 static int
18833 api_mpls_tunnel_dump (vat_main_t * vam)
18834 {
18835   vl_api_mpls_tunnel_dump_t *mp;
18836   vl_api_control_ping_t *mp_ping;
18837   i32 index = -1;
18838   int ret;
18839
18840   /* Parse args required to build the message */
18841   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18842     {
18843       if (!unformat (vam->input, "tunnel_index %d", &index))
18844         {
18845           index = -1;
18846           break;
18847         }
18848     }
18849
18850   print (vam->ofp, "  tunnel_index %d", index);
18851
18852   M (MPLS_TUNNEL_DUMP, mp);
18853   mp->tunnel_index = htonl (index);
18854   S (mp);
18855
18856   /* Use a control ping for synchronization */
18857   MPING (CONTROL_PING, mp_ping);
18858   S (mp_ping);
18859
18860   W (ret);
18861   return ret;
18862 }
18863
18864 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18865 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18866
18867
18868 static void
18869 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18870 {
18871   vat_main_t *vam = &vat_main;
18872   int count = ntohl (mp->count);
18873   vl_api_fib_path2_t *fp;
18874   int i;
18875
18876   print (vam->ofp,
18877          "table-id %d, label %u, ess_bit %u",
18878          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18879   fp = mp->path;
18880   for (i = 0; i < count; i++)
18881     {
18882       vl_api_mpls_fib_path_print (vam, fp);
18883       fp++;
18884     }
18885 }
18886
18887 static void vl_api_mpls_fib_details_t_handler_json
18888   (vl_api_mpls_fib_details_t * mp)
18889 {
18890   vat_main_t *vam = &vat_main;
18891   int count = ntohl (mp->count);
18892   vat_json_node_t *node = NULL;
18893   vl_api_fib_path2_t *fp;
18894   int i;
18895
18896   if (VAT_JSON_ARRAY != vam->json_tree.type)
18897     {
18898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18899       vat_json_init_array (&vam->json_tree);
18900     }
18901   node = vat_json_array_add (&vam->json_tree);
18902
18903   vat_json_init_object (node);
18904   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18905   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18906   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18907   vat_json_object_add_uint (node, "path_count", count);
18908   fp = mp->path;
18909   for (i = 0; i < count; i++)
18910     {
18911       vl_api_mpls_fib_path_json_print (node, fp);
18912       fp++;
18913     }
18914 }
18915
18916 static int
18917 api_mpls_fib_dump (vat_main_t * vam)
18918 {
18919   vl_api_mpls_fib_dump_t *mp;
18920   vl_api_control_ping_t *mp_ping;
18921   int ret;
18922
18923   M (MPLS_FIB_DUMP, mp);
18924   S (mp);
18925
18926   /* Use a control ping for synchronization */
18927   MPING (CONTROL_PING, mp_ping);
18928   S (mp_ping);
18929
18930   W (ret);
18931   return ret;
18932 }
18933
18934 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18935 #define vl_api_ip_fib_details_t_print vl_noop_handler
18936
18937 static void
18938 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18939 {
18940   vat_main_t *vam = &vat_main;
18941   int count = ntohl (mp->count);
18942   vl_api_fib_path_t *fp;
18943   int i;
18944
18945   print (vam->ofp,
18946          "table-id %d, prefix %U/%d",
18947          ntohl (mp->table_id), format_ip4_address, mp->address,
18948          mp->address_length);
18949   fp = mp->path;
18950   for (i = 0; i < count; i++)
18951     {
18952       if (fp->afi == IP46_TYPE_IP6)
18953         print (vam->ofp,
18954                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18955                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18956                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18957                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18958                format_ip6_address, fp->next_hop);
18959       else if (fp->afi == IP46_TYPE_IP4)
18960         print (vam->ofp,
18961                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18962                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18963                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18964                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18965                format_ip4_address, fp->next_hop);
18966       fp++;
18967     }
18968 }
18969
18970 static void vl_api_ip_fib_details_t_handler_json
18971   (vl_api_ip_fib_details_t * mp)
18972 {
18973   vat_main_t *vam = &vat_main;
18974   int count = ntohl (mp->count);
18975   vat_json_node_t *node = NULL;
18976   struct in_addr ip4;
18977   struct in6_addr ip6;
18978   vl_api_fib_path_t *fp;
18979   int i;
18980
18981   if (VAT_JSON_ARRAY != vam->json_tree.type)
18982     {
18983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18984       vat_json_init_array (&vam->json_tree);
18985     }
18986   node = vat_json_array_add (&vam->json_tree);
18987
18988   vat_json_init_object (node);
18989   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18990   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18991   vat_json_object_add_ip4 (node, "prefix", ip4);
18992   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18993   vat_json_object_add_uint (node, "path_count", count);
18994   fp = mp->path;
18995   for (i = 0; i < count; i++)
18996     {
18997       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18998       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18999       vat_json_object_add_uint (node, "is_local", fp->is_local);
19000       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19001       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19002       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19003       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19004       if (fp->afi == IP46_TYPE_IP4)
19005         {
19006           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19007           vat_json_object_add_ip4 (node, "next_hop", ip4);
19008         }
19009       else if (fp->afi == IP46_TYPE_IP6)
19010         {
19011           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19012           vat_json_object_add_ip6 (node, "next_hop", ip6);
19013         }
19014     }
19015 }
19016
19017 static int
19018 api_ip_fib_dump (vat_main_t * vam)
19019 {
19020   vl_api_ip_fib_dump_t *mp;
19021   vl_api_control_ping_t *mp_ping;
19022   int ret;
19023
19024   M (IP_FIB_DUMP, mp);
19025   S (mp);
19026
19027   /* Use a control ping for synchronization */
19028   MPING (CONTROL_PING, mp_ping);
19029   S (mp_ping);
19030
19031   W (ret);
19032   return ret;
19033 }
19034
19035 static int
19036 api_ip_mfib_dump (vat_main_t * vam)
19037 {
19038   vl_api_ip_mfib_dump_t *mp;
19039   vl_api_control_ping_t *mp_ping;
19040   int ret;
19041
19042   M (IP_MFIB_DUMP, mp);
19043   S (mp);
19044
19045   /* Use a control ping for synchronization */
19046   MPING (CONTROL_PING, mp_ping);
19047   S (mp_ping);
19048
19049   W (ret);
19050   return ret;
19051 }
19052
19053 static void vl_api_ip_neighbor_details_t_handler
19054   (vl_api_ip_neighbor_details_t * mp)
19055 {
19056   vat_main_t *vam = &vat_main;
19057
19058   print (vam->ofp, "%c %U %U",
19059          (mp->is_static) ? 'S' : 'D',
19060          format_ethernet_address, &mp->mac_address,
19061          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19062          &mp->ip_address);
19063 }
19064
19065 static void vl_api_ip_neighbor_details_t_handler_json
19066   (vl_api_ip_neighbor_details_t * mp)
19067 {
19068
19069   vat_main_t *vam = &vat_main;
19070   vat_json_node_t *node;
19071   struct in_addr ip4;
19072   struct in6_addr ip6;
19073
19074   if (VAT_JSON_ARRAY != vam->json_tree.type)
19075     {
19076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19077       vat_json_init_array (&vam->json_tree);
19078     }
19079   node = vat_json_array_add (&vam->json_tree);
19080
19081   vat_json_init_object (node);
19082   vat_json_object_add_string_copy (node, "flag",
19083                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19084                                    "dynamic");
19085
19086   vat_json_object_add_string_copy (node, "link_layer",
19087                                    format (0, "%U", format_ethernet_address,
19088                                            &mp->mac_address));
19089
19090   if (mp->is_ipv6)
19091     {
19092       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19093       vat_json_object_add_ip6 (node, "ip_address", ip6);
19094     }
19095   else
19096     {
19097       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19098       vat_json_object_add_ip4 (node, "ip_address", ip4);
19099     }
19100 }
19101
19102 static int
19103 api_ip_neighbor_dump (vat_main_t * vam)
19104 {
19105   unformat_input_t *i = vam->input;
19106   vl_api_ip_neighbor_dump_t *mp;
19107   vl_api_control_ping_t *mp_ping;
19108   u8 is_ipv6 = 0;
19109   u32 sw_if_index = ~0;
19110   int ret;
19111
19112   /* Parse args required to build the message */
19113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19114     {
19115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19116         ;
19117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19118         ;
19119       else if (unformat (i, "ip6"))
19120         is_ipv6 = 1;
19121       else
19122         break;
19123     }
19124
19125   if (sw_if_index == ~0)
19126     {
19127       errmsg ("missing interface name or sw_if_index");
19128       return -99;
19129     }
19130
19131   M (IP_NEIGHBOR_DUMP, mp);
19132   mp->is_ipv6 = (u8) is_ipv6;
19133   mp->sw_if_index = ntohl (sw_if_index);
19134   S (mp);
19135
19136   /* Use a control ping for synchronization */
19137   MPING (CONTROL_PING, mp_ping);
19138   S (mp_ping);
19139
19140   W (ret);
19141   return ret;
19142 }
19143
19144 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19145 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19146
19147 static void
19148 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19149 {
19150   vat_main_t *vam = &vat_main;
19151   int count = ntohl (mp->count);
19152   vl_api_fib_path_t *fp;
19153   int i;
19154
19155   print (vam->ofp,
19156          "table-id %d, prefix %U/%d",
19157          ntohl (mp->table_id), format_ip6_address, mp->address,
19158          mp->address_length);
19159   fp = mp->path;
19160   for (i = 0; i < count; i++)
19161     {
19162       if (fp->afi == IP46_TYPE_IP6)
19163         print (vam->ofp,
19164                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19165                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19166                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19167                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19168                format_ip6_address, fp->next_hop);
19169       else if (fp->afi == IP46_TYPE_IP4)
19170         print (vam->ofp,
19171                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19172                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19173                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19174                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19175                format_ip4_address, fp->next_hop);
19176       fp++;
19177     }
19178 }
19179
19180 static void vl_api_ip6_fib_details_t_handler_json
19181   (vl_api_ip6_fib_details_t * mp)
19182 {
19183   vat_main_t *vam = &vat_main;
19184   int count = ntohl (mp->count);
19185   vat_json_node_t *node = NULL;
19186   struct in_addr ip4;
19187   struct in6_addr ip6;
19188   vl_api_fib_path_t *fp;
19189   int i;
19190
19191   if (VAT_JSON_ARRAY != vam->json_tree.type)
19192     {
19193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19194       vat_json_init_array (&vam->json_tree);
19195     }
19196   node = vat_json_array_add (&vam->json_tree);
19197
19198   vat_json_init_object (node);
19199   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19200   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19201   vat_json_object_add_ip6 (node, "prefix", ip6);
19202   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19203   vat_json_object_add_uint (node, "path_count", count);
19204   fp = mp->path;
19205   for (i = 0; i < count; i++)
19206     {
19207       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19208       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19209       vat_json_object_add_uint (node, "is_local", fp->is_local);
19210       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19211       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19212       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19213       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19214       if (fp->afi == IP46_TYPE_IP4)
19215         {
19216           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19217           vat_json_object_add_ip4 (node, "next_hop", ip4);
19218         }
19219       else if (fp->afi == IP46_TYPE_IP6)
19220         {
19221           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19222           vat_json_object_add_ip6 (node, "next_hop", ip6);
19223         }
19224     }
19225 }
19226
19227 static int
19228 api_ip6_fib_dump (vat_main_t * vam)
19229 {
19230   vl_api_ip6_fib_dump_t *mp;
19231   vl_api_control_ping_t *mp_ping;
19232   int ret;
19233
19234   M (IP6_FIB_DUMP, mp);
19235   S (mp);
19236
19237   /* Use a control ping for synchronization */
19238   MPING (CONTROL_PING, mp_ping);
19239   S (mp_ping);
19240
19241   W (ret);
19242   return ret;
19243 }
19244
19245 static int
19246 api_ip6_mfib_dump (vat_main_t * vam)
19247 {
19248   vl_api_ip6_mfib_dump_t *mp;
19249   vl_api_control_ping_t *mp_ping;
19250   int ret;
19251
19252   M (IP6_MFIB_DUMP, mp);
19253   S (mp);
19254
19255   /* Use a control ping for synchronization */
19256   MPING (CONTROL_PING, mp_ping);
19257   S (mp_ping);
19258
19259   W (ret);
19260   return ret;
19261 }
19262
19263 int
19264 api_classify_table_ids (vat_main_t * vam)
19265 {
19266   vl_api_classify_table_ids_t *mp;
19267   int ret;
19268
19269   /* Construct the API message */
19270   M (CLASSIFY_TABLE_IDS, mp);
19271   mp->context = 0;
19272
19273   S (mp);
19274   W (ret);
19275   return ret;
19276 }
19277
19278 int
19279 api_classify_table_by_interface (vat_main_t * vam)
19280 {
19281   unformat_input_t *input = vam->input;
19282   vl_api_classify_table_by_interface_t *mp;
19283
19284   u32 sw_if_index = ~0;
19285   int ret;
19286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19287     {
19288       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19289         ;
19290       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19291         ;
19292       else
19293         break;
19294     }
19295   if (sw_if_index == ~0)
19296     {
19297       errmsg ("missing interface name or sw_if_index");
19298       return -99;
19299     }
19300
19301   /* Construct the API message */
19302   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19303   mp->context = 0;
19304   mp->sw_if_index = ntohl (sw_if_index);
19305
19306   S (mp);
19307   W (ret);
19308   return ret;
19309 }
19310
19311 int
19312 api_classify_table_info (vat_main_t * vam)
19313 {
19314   unformat_input_t *input = vam->input;
19315   vl_api_classify_table_info_t *mp;
19316
19317   u32 table_id = ~0;
19318   int ret;
19319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19320     {
19321       if (unformat (input, "table_id %d", &table_id))
19322         ;
19323       else
19324         break;
19325     }
19326   if (table_id == ~0)
19327     {
19328       errmsg ("missing table id");
19329       return -99;
19330     }
19331
19332   /* Construct the API message */
19333   M (CLASSIFY_TABLE_INFO, mp);
19334   mp->context = 0;
19335   mp->table_id = ntohl (table_id);
19336
19337   S (mp);
19338   W (ret);
19339   return ret;
19340 }
19341
19342 int
19343 api_classify_session_dump (vat_main_t * vam)
19344 {
19345   unformat_input_t *input = vam->input;
19346   vl_api_classify_session_dump_t *mp;
19347   vl_api_control_ping_t *mp_ping;
19348
19349   u32 table_id = ~0;
19350   int ret;
19351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19352     {
19353       if (unformat (input, "table_id %d", &table_id))
19354         ;
19355       else
19356         break;
19357     }
19358   if (table_id == ~0)
19359     {
19360       errmsg ("missing table id");
19361       return -99;
19362     }
19363
19364   /* Construct the API message */
19365   M (CLASSIFY_SESSION_DUMP, mp);
19366   mp->context = 0;
19367   mp->table_id = ntohl (table_id);
19368   S (mp);
19369
19370   /* Use a control ping for synchronization */
19371   MPING (CONTROL_PING, mp_ping);
19372   S (mp_ping);
19373
19374   W (ret);
19375   return ret;
19376 }
19377
19378 static void
19379 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19380 {
19381   vat_main_t *vam = &vat_main;
19382
19383   print (vam->ofp, "collector_address %U, collector_port %d, "
19384          "src_address %U, vrf_id %d, path_mtu %u, "
19385          "template_interval %u, udp_checksum %d",
19386          format_ip4_address, mp->collector_address,
19387          ntohs (mp->collector_port),
19388          format_ip4_address, mp->src_address,
19389          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19390          ntohl (mp->template_interval), mp->udp_checksum);
19391
19392   vam->retval = 0;
19393   vam->result_ready = 1;
19394 }
19395
19396 static void
19397   vl_api_ipfix_exporter_details_t_handler_json
19398   (vl_api_ipfix_exporter_details_t * mp)
19399 {
19400   vat_main_t *vam = &vat_main;
19401   vat_json_node_t node;
19402   struct in_addr collector_address;
19403   struct in_addr src_address;
19404
19405   vat_json_init_object (&node);
19406   clib_memcpy (&collector_address, &mp->collector_address,
19407                sizeof (collector_address));
19408   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19409   vat_json_object_add_uint (&node, "collector_port",
19410                             ntohs (mp->collector_port));
19411   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19412   vat_json_object_add_ip4 (&node, "src_address", src_address);
19413   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19414   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19415   vat_json_object_add_uint (&node, "template_interval",
19416                             ntohl (mp->template_interval));
19417   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19418
19419   vat_json_print (vam->ofp, &node);
19420   vat_json_free (&node);
19421   vam->retval = 0;
19422   vam->result_ready = 1;
19423 }
19424
19425 int
19426 api_ipfix_exporter_dump (vat_main_t * vam)
19427 {
19428   vl_api_ipfix_exporter_dump_t *mp;
19429   int ret;
19430
19431   /* Construct the API message */
19432   M (IPFIX_EXPORTER_DUMP, mp);
19433   mp->context = 0;
19434
19435   S (mp);
19436   W (ret);
19437   return ret;
19438 }
19439
19440 static int
19441 api_ipfix_classify_stream_dump (vat_main_t * vam)
19442 {
19443   vl_api_ipfix_classify_stream_dump_t *mp;
19444   int ret;
19445
19446   /* Construct the API message */
19447   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19448   mp->context = 0;
19449
19450   S (mp);
19451   W (ret);
19452   return ret;
19453   /* NOTREACHED */
19454   return 0;
19455 }
19456
19457 static void
19458   vl_api_ipfix_classify_stream_details_t_handler
19459   (vl_api_ipfix_classify_stream_details_t * mp)
19460 {
19461   vat_main_t *vam = &vat_main;
19462   print (vam->ofp, "domain_id %d, src_port %d",
19463          ntohl (mp->domain_id), ntohs (mp->src_port));
19464   vam->retval = 0;
19465   vam->result_ready = 1;
19466 }
19467
19468 static void
19469   vl_api_ipfix_classify_stream_details_t_handler_json
19470   (vl_api_ipfix_classify_stream_details_t * mp)
19471 {
19472   vat_main_t *vam = &vat_main;
19473   vat_json_node_t node;
19474
19475   vat_json_init_object (&node);
19476   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19477   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19478
19479   vat_json_print (vam->ofp, &node);
19480   vat_json_free (&node);
19481   vam->retval = 0;
19482   vam->result_ready = 1;
19483 }
19484
19485 static int
19486 api_ipfix_classify_table_dump (vat_main_t * vam)
19487 {
19488   vl_api_ipfix_classify_table_dump_t *mp;
19489   vl_api_control_ping_t *mp_ping;
19490   int ret;
19491
19492   if (!vam->json_output)
19493     {
19494       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19495              "transport_protocol");
19496     }
19497
19498   /* Construct the API message */
19499   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19500
19501   /* send it... */
19502   S (mp);
19503
19504   /* Use a control ping for synchronization */
19505   MPING (CONTROL_PING, mp_ping);
19506   S (mp_ping);
19507
19508   W (ret);
19509   return ret;
19510 }
19511
19512 static void
19513   vl_api_ipfix_classify_table_details_t_handler
19514   (vl_api_ipfix_classify_table_details_t * mp)
19515 {
19516   vat_main_t *vam = &vat_main;
19517   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19518          mp->transport_protocol);
19519 }
19520
19521 static void
19522   vl_api_ipfix_classify_table_details_t_handler_json
19523   (vl_api_ipfix_classify_table_details_t * mp)
19524 {
19525   vat_json_node_t *node = NULL;
19526   vat_main_t *vam = &vat_main;
19527
19528   if (VAT_JSON_ARRAY != vam->json_tree.type)
19529     {
19530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19531       vat_json_init_array (&vam->json_tree);
19532     }
19533
19534   node = vat_json_array_add (&vam->json_tree);
19535   vat_json_init_object (node);
19536
19537   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19538   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19539   vat_json_object_add_uint (node, "transport_protocol",
19540                             mp->transport_protocol);
19541 }
19542
19543 static int
19544 api_sw_interface_span_enable_disable (vat_main_t * vam)
19545 {
19546   unformat_input_t *i = vam->input;
19547   vl_api_sw_interface_span_enable_disable_t *mp;
19548   u32 src_sw_if_index = ~0;
19549   u32 dst_sw_if_index = ~0;
19550   u8 state = 3;
19551   int ret;
19552   u8 is_l2 = 0;
19553
19554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19555     {
19556       if (unformat
19557           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19558         ;
19559       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19560         ;
19561       else
19562         if (unformat
19563             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19564         ;
19565       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19566         ;
19567       else if (unformat (i, "disable"))
19568         state = 0;
19569       else if (unformat (i, "rx"))
19570         state = 1;
19571       else if (unformat (i, "tx"))
19572         state = 2;
19573       else if (unformat (i, "both"))
19574         state = 3;
19575       else if (unformat (i, "l2"))
19576         is_l2 = 1;
19577       else
19578         break;
19579     }
19580
19581   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19582
19583   mp->sw_if_index_from = htonl (src_sw_if_index);
19584   mp->sw_if_index_to = htonl (dst_sw_if_index);
19585   mp->state = state;
19586   mp->is_l2 = is_l2;
19587
19588   S (mp);
19589   W (ret);
19590   return ret;
19591 }
19592
19593 static void
19594 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19595                                             * mp)
19596 {
19597   vat_main_t *vam = &vat_main;
19598   u8 *sw_if_from_name = 0;
19599   u8 *sw_if_to_name = 0;
19600   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19601   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19602   char *states[] = { "none", "rx", "tx", "both" };
19603   hash_pair_t *p;
19604
19605   /* *INDENT-OFF* */
19606   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19607   ({
19608     if ((u32) p->value[0] == sw_if_index_from)
19609       {
19610         sw_if_from_name = (u8 *)(p->key);
19611         if (sw_if_to_name)
19612           break;
19613       }
19614     if ((u32) p->value[0] == sw_if_index_to)
19615       {
19616         sw_if_to_name = (u8 *)(p->key);
19617         if (sw_if_from_name)
19618           break;
19619       }
19620   }));
19621   /* *INDENT-ON* */
19622   print (vam->ofp, "%20s => %20s (%s)",
19623          sw_if_from_name, sw_if_to_name, states[mp->state]);
19624 }
19625
19626 static void
19627   vl_api_sw_interface_span_details_t_handler_json
19628   (vl_api_sw_interface_span_details_t * mp)
19629 {
19630   vat_main_t *vam = &vat_main;
19631   vat_json_node_t *node = NULL;
19632   u8 *sw_if_from_name = 0;
19633   u8 *sw_if_to_name = 0;
19634   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19635   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19636   hash_pair_t *p;
19637
19638   /* *INDENT-OFF* */
19639   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19640   ({
19641     if ((u32) p->value[0] == sw_if_index_from)
19642       {
19643         sw_if_from_name = (u8 *)(p->key);
19644         if (sw_if_to_name)
19645           break;
19646       }
19647     if ((u32) p->value[0] == sw_if_index_to)
19648       {
19649         sw_if_to_name = (u8 *)(p->key);
19650         if (sw_if_from_name)
19651           break;
19652       }
19653   }));
19654   /* *INDENT-ON* */
19655
19656   if (VAT_JSON_ARRAY != vam->json_tree.type)
19657     {
19658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19659       vat_json_init_array (&vam->json_tree);
19660     }
19661   node = vat_json_array_add (&vam->json_tree);
19662
19663   vat_json_init_object (node);
19664   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19665   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19666   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19667   if (0 != sw_if_to_name)
19668     {
19669       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19670     }
19671   vat_json_object_add_uint (node, "state", mp->state);
19672 }
19673
19674 static int
19675 api_sw_interface_span_dump (vat_main_t * vam)
19676 {
19677   unformat_input_t *input = vam->input;
19678   vl_api_sw_interface_span_dump_t *mp;
19679   vl_api_control_ping_t *mp_ping;
19680   u8 is_l2 = 0;
19681   int ret;
19682
19683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19684     {
19685       if (unformat (input, "l2"))
19686         is_l2 = 1;
19687       else
19688         break;
19689     }
19690
19691   M (SW_INTERFACE_SPAN_DUMP, mp);
19692   mp->is_l2 = is_l2;
19693   S (mp);
19694
19695   /* Use a control ping for synchronization */
19696   MPING (CONTROL_PING, mp_ping);
19697   S (mp_ping);
19698
19699   W (ret);
19700   return ret;
19701 }
19702
19703 int
19704 api_pg_create_interface (vat_main_t * vam)
19705 {
19706   unformat_input_t *input = vam->input;
19707   vl_api_pg_create_interface_t *mp;
19708
19709   u32 if_id = ~0;
19710   int ret;
19711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19712     {
19713       if (unformat (input, "if_id %d", &if_id))
19714         ;
19715       else
19716         break;
19717     }
19718   if (if_id == ~0)
19719     {
19720       errmsg ("missing pg interface index");
19721       return -99;
19722     }
19723
19724   /* Construct the API message */
19725   M (PG_CREATE_INTERFACE, mp);
19726   mp->context = 0;
19727   mp->interface_id = ntohl (if_id);
19728
19729   S (mp);
19730   W (ret);
19731   return ret;
19732 }
19733
19734 int
19735 api_pg_capture (vat_main_t * vam)
19736 {
19737   unformat_input_t *input = vam->input;
19738   vl_api_pg_capture_t *mp;
19739
19740   u32 if_id = ~0;
19741   u8 enable = 1;
19742   u32 count = 1;
19743   u8 pcap_file_set = 0;
19744   u8 *pcap_file = 0;
19745   int ret;
19746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19747     {
19748       if (unformat (input, "if_id %d", &if_id))
19749         ;
19750       else if (unformat (input, "pcap %s", &pcap_file))
19751         pcap_file_set = 1;
19752       else if (unformat (input, "count %d", &count))
19753         ;
19754       else if (unformat (input, "disable"))
19755         enable = 0;
19756       else
19757         break;
19758     }
19759   if (if_id == ~0)
19760     {
19761       errmsg ("missing pg interface index");
19762       return -99;
19763     }
19764   if (pcap_file_set > 0)
19765     {
19766       if (vec_len (pcap_file) > 255)
19767         {
19768           errmsg ("pcap file name is too long");
19769           return -99;
19770         }
19771     }
19772
19773   u32 name_len = vec_len (pcap_file);
19774   /* Construct the API message */
19775   M (PG_CAPTURE, mp);
19776   mp->context = 0;
19777   mp->interface_id = ntohl (if_id);
19778   mp->is_enabled = enable;
19779   mp->count = ntohl (count);
19780   mp->pcap_name_length = ntohl (name_len);
19781   if (pcap_file_set != 0)
19782     {
19783       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19784     }
19785   vec_free (pcap_file);
19786
19787   S (mp);
19788   W (ret);
19789   return ret;
19790 }
19791
19792 int
19793 api_pg_enable_disable (vat_main_t * vam)
19794 {
19795   unformat_input_t *input = vam->input;
19796   vl_api_pg_enable_disable_t *mp;
19797
19798   u8 enable = 1;
19799   u8 stream_name_set = 0;
19800   u8 *stream_name = 0;
19801   int ret;
19802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19803     {
19804       if (unformat (input, "stream %s", &stream_name))
19805         stream_name_set = 1;
19806       else if (unformat (input, "disable"))
19807         enable = 0;
19808       else
19809         break;
19810     }
19811
19812   if (stream_name_set > 0)
19813     {
19814       if (vec_len (stream_name) > 255)
19815         {
19816           errmsg ("stream name too long");
19817           return -99;
19818         }
19819     }
19820
19821   u32 name_len = vec_len (stream_name);
19822   /* Construct the API message */
19823   M (PG_ENABLE_DISABLE, mp);
19824   mp->context = 0;
19825   mp->is_enabled = enable;
19826   if (stream_name_set != 0)
19827     {
19828       mp->stream_name_length = ntohl (name_len);
19829       clib_memcpy (mp->stream_name, stream_name, name_len);
19830     }
19831   vec_free (stream_name);
19832
19833   S (mp);
19834   W (ret);
19835   return ret;
19836 }
19837
19838 int
19839 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19840 {
19841   unformat_input_t *input = vam->input;
19842   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19843
19844   u16 *low_ports = 0;
19845   u16 *high_ports = 0;
19846   u16 this_low;
19847   u16 this_hi;
19848   ip4_address_t ip4_addr;
19849   ip6_address_t ip6_addr;
19850   u32 length;
19851   u32 tmp, tmp2;
19852   u8 prefix_set = 0;
19853   u32 vrf_id = ~0;
19854   u8 is_add = 1;
19855   u8 is_ipv6 = 0;
19856   int ret;
19857
19858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19859     {
19860       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19861         {
19862           prefix_set = 1;
19863         }
19864       else
19865         if (unformat
19866             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19867         {
19868           prefix_set = 1;
19869           is_ipv6 = 1;
19870         }
19871       else if (unformat (input, "vrf %d", &vrf_id))
19872         ;
19873       else if (unformat (input, "del"))
19874         is_add = 0;
19875       else if (unformat (input, "port %d", &tmp))
19876         {
19877           if (tmp == 0 || tmp > 65535)
19878             {
19879               errmsg ("port %d out of range", tmp);
19880               return -99;
19881             }
19882           this_low = tmp;
19883           this_hi = this_low + 1;
19884           vec_add1 (low_ports, this_low);
19885           vec_add1 (high_ports, this_hi);
19886         }
19887       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19888         {
19889           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19890             {
19891               errmsg ("incorrect range parameters");
19892               return -99;
19893             }
19894           this_low = tmp;
19895           /* Note: in debug CLI +1 is added to high before
19896              passing to real fn that does "the work"
19897              (ip_source_and_port_range_check_add_del).
19898              This fn is a wrapper around the binary API fn a
19899              control plane will call, which expects this increment
19900              to have occurred. Hence letting the binary API control
19901              plane fn do the increment for consistency between VAT
19902              and other control planes.
19903            */
19904           this_hi = tmp2;
19905           vec_add1 (low_ports, this_low);
19906           vec_add1 (high_ports, this_hi);
19907         }
19908       else
19909         break;
19910     }
19911
19912   if (prefix_set == 0)
19913     {
19914       errmsg ("<address>/<mask> not specified");
19915       return -99;
19916     }
19917
19918   if (vrf_id == ~0)
19919     {
19920       errmsg ("VRF ID required, not specified");
19921       return -99;
19922     }
19923
19924   if (vrf_id == 0)
19925     {
19926       errmsg
19927         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19928       return -99;
19929     }
19930
19931   if (vec_len (low_ports) == 0)
19932     {
19933       errmsg ("At least one port or port range required");
19934       return -99;
19935     }
19936
19937   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19938
19939   mp->is_add = is_add;
19940
19941   if (is_ipv6)
19942     {
19943       mp->is_ipv6 = 1;
19944       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19945     }
19946   else
19947     {
19948       mp->is_ipv6 = 0;
19949       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19950     }
19951
19952   mp->mask_length = length;
19953   mp->number_of_ranges = vec_len (low_ports);
19954
19955   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19956   vec_free (low_ports);
19957
19958   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19959   vec_free (high_ports);
19960
19961   mp->vrf_id = ntohl (vrf_id);
19962
19963   S (mp);
19964   W (ret);
19965   return ret;
19966 }
19967
19968 int
19969 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19970 {
19971   unformat_input_t *input = vam->input;
19972   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19973   u32 sw_if_index = ~0;
19974   int vrf_set = 0;
19975   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19976   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19977   u8 is_add = 1;
19978   int ret;
19979
19980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19981     {
19982       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19983         ;
19984       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19985         ;
19986       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19987         vrf_set = 1;
19988       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19989         vrf_set = 1;
19990       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19991         vrf_set = 1;
19992       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19993         vrf_set = 1;
19994       else if (unformat (input, "del"))
19995         is_add = 0;
19996       else
19997         break;
19998     }
19999
20000   if (sw_if_index == ~0)
20001     {
20002       errmsg ("Interface required but not specified");
20003       return -99;
20004     }
20005
20006   if (vrf_set == 0)
20007     {
20008       errmsg ("VRF ID required but not specified");
20009       return -99;
20010     }
20011
20012   if (tcp_out_vrf_id == 0
20013       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20014     {
20015       errmsg
20016         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20017       return -99;
20018     }
20019
20020   /* Construct the API message */
20021   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20022
20023   mp->sw_if_index = ntohl (sw_if_index);
20024   mp->is_add = is_add;
20025   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20026   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20027   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20028   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20029
20030   /* send it... */
20031   S (mp);
20032
20033   /* Wait for a reply... */
20034   W (ret);
20035   return ret;
20036 }
20037
20038 static int
20039 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20040 {
20041   unformat_input_t *i = vam->input;
20042   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20043   u32 local_sa_id = 0;
20044   u32 remote_sa_id = 0;
20045   ip4_address_t src_address;
20046   ip4_address_t dst_address;
20047   u8 is_add = 1;
20048   int ret;
20049
20050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20051     {
20052       if (unformat (i, "local_sa %d", &local_sa_id))
20053         ;
20054       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20055         ;
20056       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20057         ;
20058       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20059         ;
20060       else if (unformat (i, "del"))
20061         is_add = 0;
20062       else
20063         {
20064           clib_warning ("parse error '%U'", format_unformat_error, i);
20065           return -99;
20066         }
20067     }
20068
20069   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20070
20071   mp->local_sa_id = ntohl (local_sa_id);
20072   mp->remote_sa_id = ntohl (remote_sa_id);
20073   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20074   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20075   mp->is_add = is_add;
20076
20077   S (mp);
20078   W (ret);
20079   return ret;
20080 }
20081
20082 static int
20083 api_punt (vat_main_t * vam)
20084 {
20085   unformat_input_t *i = vam->input;
20086   vl_api_punt_t *mp;
20087   u32 ipv = ~0;
20088   u32 protocol = ~0;
20089   u32 port = ~0;
20090   int is_add = 1;
20091   int ret;
20092
20093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20094     {
20095       if (unformat (i, "ip %d", &ipv))
20096         ;
20097       else if (unformat (i, "protocol %d", &protocol))
20098         ;
20099       else if (unformat (i, "port %d", &port))
20100         ;
20101       else if (unformat (i, "del"))
20102         is_add = 0;
20103       else
20104         {
20105           clib_warning ("parse error '%U'", format_unformat_error, i);
20106           return -99;
20107         }
20108     }
20109
20110   M (PUNT, mp);
20111
20112   mp->is_add = (u8) is_add;
20113   mp->ipv = (u8) ipv;
20114   mp->l4_protocol = (u8) protocol;
20115   mp->l4_port = htons ((u16) port);
20116
20117   S (mp);
20118   W (ret);
20119   return ret;
20120 }
20121
20122 static void vl_api_ipsec_gre_tunnel_details_t_handler
20123   (vl_api_ipsec_gre_tunnel_details_t * mp)
20124 {
20125   vat_main_t *vam = &vat_main;
20126
20127   print (vam->ofp, "%11d%15U%15U%14d%14d",
20128          ntohl (mp->sw_if_index),
20129          format_ip4_address, &mp->src_address,
20130          format_ip4_address, &mp->dst_address,
20131          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20132 }
20133
20134 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20135   (vl_api_ipsec_gre_tunnel_details_t * mp)
20136 {
20137   vat_main_t *vam = &vat_main;
20138   vat_json_node_t *node = NULL;
20139   struct in_addr ip4;
20140
20141   if (VAT_JSON_ARRAY != vam->json_tree.type)
20142     {
20143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20144       vat_json_init_array (&vam->json_tree);
20145     }
20146   node = vat_json_array_add (&vam->json_tree);
20147
20148   vat_json_init_object (node);
20149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20150   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20151   vat_json_object_add_ip4 (node, "src_address", ip4);
20152   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20153   vat_json_object_add_ip4 (node, "dst_address", ip4);
20154   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20155   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20156 }
20157
20158 static int
20159 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20160 {
20161   unformat_input_t *i = vam->input;
20162   vl_api_ipsec_gre_tunnel_dump_t *mp;
20163   vl_api_control_ping_t *mp_ping;
20164   u32 sw_if_index;
20165   u8 sw_if_index_set = 0;
20166   int ret;
20167
20168   /* Parse args required to build the message */
20169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20170     {
20171       if (unformat (i, "sw_if_index %d", &sw_if_index))
20172         sw_if_index_set = 1;
20173       else
20174         break;
20175     }
20176
20177   if (sw_if_index_set == 0)
20178     {
20179       sw_if_index = ~0;
20180     }
20181
20182   if (!vam->json_output)
20183     {
20184       print (vam->ofp, "%11s%15s%15s%14s%14s",
20185              "sw_if_index", "src_address", "dst_address",
20186              "local_sa_id", "remote_sa_id");
20187     }
20188
20189   /* Get list of gre-tunnel interfaces */
20190   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20191
20192   mp->sw_if_index = htonl (sw_if_index);
20193
20194   S (mp);
20195
20196   /* Use a control ping for synchronization */
20197   MPING (CONTROL_PING, mp_ping);
20198   S (mp_ping);
20199
20200   W (ret);
20201   return ret;
20202 }
20203
20204 static int
20205 api_delete_subif (vat_main_t * vam)
20206 {
20207   unformat_input_t *i = vam->input;
20208   vl_api_delete_subif_t *mp;
20209   u32 sw_if_index = ~0;
20210   int ret;
20211
20212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20213     {
20214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20215         ;
20216       if (unformat (i, "sw_if_index %d", &sw_if_index))
20217         ;
20218       else
20219         break;
20220     }
20221
20222   if (sw_if_index == ~0)
20223     {
20224       errmsg ("missing sw_if_index");
20225       return -99;
20226     }
20227
20228   /* Construct the API message */
20229   M (DELETE_SUBIF, mp);
20230   mp->sw_if_index = ntohl (sw_if_index);
20231
20232   S (mp);
20233   W (ret);
20234   return ret;
20235 }
20236
20237 #define foreach_pbb_vtr_op      \
20238 _("disable",  L2_VTR_DISABLED)  \
20239 _("pop",  L2_VTR_POP_2)         \
20240 _("push",  L2_VTR_PUSH_2)
20241
20242 static int
20243 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20244 {
20245   unformat_input_t *i = vam->input;
20246   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20247   u32 sw_if_index = ~0, vtr_op = ~0;
20248   u16 outer_tag = ~0;
20249   u8 dmac[6], smac[6];
20250   u8 dmac_set = 0, smac_set = 0;
20251   u16 vlanid = 0;
20252   u32 sid = ~0;
20253   u32 tmp;
20254   int ret;
20255
20256   /* Shut up coverity */
20257   memset (dmac, 0, sizeof (dmac));
20258   memset (smac, 0, sizeof (smac));
20259
20260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20261     {
20262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20263         ;
20264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20265         ;
20266       else if (unformat (i, "vtr_op %d", &vtr_op))
20267         ;
20268 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20269       foreach_pbb_vtr_op
20270 #undef _
20271         else if (unformat (i, "translate_pbb_stag"))
20272         {
20273           if (unformat (i, "%d", &tmp))
20274             {
20275               vtr_op = L2_VTR_TRANSLATE_2_1;
20276               outer_tag = tmp;
20277             }
20278           else
20279             {
20280               errmsg
20281                 ("translate_pbb_stag operation requires outer tag definition");
20282               return -99;
20283             }
20284         }
20285       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20286         dmac_set++;
20287       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20288         smac_set++;
20289       else if (unformat (i, "sid %d", &sid))
20290         ;
20291       else if (unformat (i, "vlanid %d", &tmp))
20292         vlanid = tmp;
20293       else
20294         {
20295           clib_warning ("parse error '%U'", format_unformat_error, i);
20296           return -99;
20297         }
20298     }
20299
20300   if ((sw_if_index == ~0) || (vtr_op == ~0))
20301     {
20302       errmsg ("missing sw_if_index or vtr operation");
20303       return -99;
20304     }
20305   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20306       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20307     {
20308       errmsg
20309         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20310       return -99;
20311     }
20312
20313   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20314   mp->sw_if_index = ntohl (sw_if_index);
20315   mp->vtr_op = ntohl (vtr_op);
20316   mp->outer_tag = ntohs (outer_tag);
20317   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20318   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20319   mp->b_vlanid = ntohs (vlanid);
20320   mp->i_sid = ntohl (sid);
20321
20322   S (mp);
20323   W (ret);
20324   return ret;
20325 }
20326
20327 static int
20328 api_flow_classify_set_interface (vat_main_t * vam)
20329 {
20330   unformat_input_t *i = vam->input;
20331   vl_api_flow_classify_set_interface_t *mp;
20332   u32 sw_if_index;
20333   int sw_if_index_set;
20334   u32 ip4_table_index = ~0;
20335   u32 ip6_table_index = ~0;
20336   u8 is_add = 1;
20337   int ret;
20338
20339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20340     {
20341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20342         sw_if_index_set = 1;
20343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20344         sw_if_index_set = 1;
20345       else if (unformat (i, "del"))
20346         is_add = 0;
20347       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20348         ;
20349       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20350         ;
20351       else
20352         {
20353           clib_warning ("parse error '%U'", format_unformat_error, i);
20354           return -99;
20355         }
20356     }
20357
20358   if (sw_if_index_set == 0)
20359     {
20360       errmsg ("missing interface name or sw_if_index");
20361       return -99;
20362     }
20363
20364   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20365
20366   mp->sw_if_index = ntohl (sw_if_index);
20367   mp->ip4_table_index = ntohl (ip4_table_index);
20368   mp->ip6_table_index = ntohl (ip6_table_index);
20369   mp->is_add = is_add;
20370
20371   S (mp);
20372   W (ret);
20373   return ret;
20374 }
20375
20376 static int
20377 api_flow_classify_dump (vat_main_t * vam)
20378 {
20379   unformat_input_t *i = vam->input;
20380   vl_api_flow_classify_dump_t *mp;
20381   vl_api_control_ping_t *mp_ping;
20382   u8 type = FLOW_CLASSIFY_N_TABLES;
20383   int ret;
20384
20385   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20386     ;
20387   else
20388     {
20389       errmsg ("classify table type must be specified");
20390       return -99;
20391     }
20392
20393   if (!vam->json_output)
20394     {
20395       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20396     }
20397
20398   M (FLOW_CLASSIFY_DUMP, mp);
20399   mp->type = type;
20400   /* send it... */
20401   S (mp);
20402
20403   /* Use a control ping for synchronization */
20404   MPING (CONTROL_PING, mp_ping);
20405   S (mp_ping);
20406
20407   /* Wait for a reply... */
20408   W (ret);
20409   return ret;
20410 }
20411
20412 static int
20413 api_feature_enable_disable (vat_main_t * vam)
20414 {
20415   unformat_input_t *i = vam->input;
20416   vl_api_feature_enable_disable_t *mp;
20417   u8 *arc_name = 0;
20418   u8 *feature_name = 0;
20419   u32 sw_if_index = ~0;
20420   u8 enable = 1;
20421   int ret;
20422
20423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20424     {
20425       if (unformat (i, "arc_name %s", &arc_name))
20426         ;
20427       else if (unformat (i, "feature_name %s", &feature_name))
20428         ;
20429       else
20430         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20431         ;
20432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20433         ;
20434       else if (unformat (i, "disable"))
20435         enable = 0;
20436       else
20437         break;
20438     }
20439
20440   if (arc_name == 0)
20441     {
20442       errmsg ("missing arc name");
20443       return -99;
20444     }
20445   if (vec_len (arc_name) > 63)
20446     {
20447       errmsg ("arc name too long");
20448     }
20449
20450   if (feature_name == 0)
20451     {
20452       errmsg ("missing feature name");
20453       return -99;
20454     }
20455   if (vec_len (feature_name) > 63)
20456     {
20457       errmsg ("feature name too long");
20458     }
20459
20460   if (sw_if_index == ~0)
20461     {
20462       errmsg ("missing interface name or sw_if_index");
20463       return -99;
20464     }
20465
20466   /* Construct the API message */
20467   M (FEATURE_ENABLE_DISABLE, mp);
20468   mp->sw_if_index = ntohl (sw_if_index);
20469   mp->enable = enable;
20470   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20471   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20472   vec_free (arc_name);
20473   vec_free (feature_name);
20474
20475   S (mp);
20476   W (ret);
20477   return ret;
20478 }
20479
20480 static int
20481 api_sw_interface_tag_add_del (vat_main_t * vam)
20482 {
20483   unformat_input_t *i = vam->input;
20484   vl_api_sw_interface_tag_add_del_t *mp;
20485   u32 sw_if_index = ~0;
20486   u8 *tag = 0;
20487   u8 enable = 1;
20488   int ret;
20489
20490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20491     {
20492       if (unformat (i, "tag %s", &tag))
20493         ;
20494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20495         ;
20496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20497         ;
20498       else if (unformat (i, "del"))
20499         enable = 0;
20500       else
20501         break;
20502     }
20503
20504   if (sw_if_index == ~0)
20505     {
20506       errmsg ("missing interface name or sw_if_index");
20507       return -99;
20508     }
20509
20510   if (enable && (tag == 0))
20511     {
20512       errmsg ("no tag specified");
20513       return -99;
20514     }
20515
20516   /* Construct the API message */
20517   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20518   mp->sw_if_index = ntohl (sw_if_index);
20519   mp->is_add = enable;
20520   if (enable)
20521     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20522   vec_free (tag);
20523
20524   S (mp);
20525   W (ret);
20526   return ret;
20527 }
20528
20529 static void vl_api_l2_xconnect_details_t_handler
20530   (vl_api_l2_xconnect_details_t * mp)
20531 {
20532   vat_main_t *vam = &vat_main;
20533
20534   print (vam->ofp, "%15d%15d",
20535          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20536 }
20537
20538 static void vl_api_l2_xconnect_details_t_handler_json
20539   (vl_api_l2_xconnect_details_t * mp)
20540 {
20541   vat_main_t *vam = &vat_main;
20542   vat_json_node_t *node = NULL;
20543
20544   if (VAT_JSON_ARRAY != vam->json_tree.type)
20545     {
20546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20547       vat_json_init_array (&vam->json_tree);
20548     }
20549   node = vat_json_array_add (&vam->json_tree);
20550
20551   vat_json_init_object (node);
20552   vat_json_object_add_uint (node, "rx_sw_if_index",
20553                             ntohl (mp->rx_sw_if_index));
20554   vat_json_object_add_uint (node, "tx_sw_if_index",
20555                             ntohl (mp->tx_sw_if_index));
20556 }
20557
20558 static int
20559 api_l2_xconnect_dump (vat_main_t * vam)
20560 {
20561   vl_api_l2_xconnect_dump_t *mp;
20562   vl_api_control_ping_t *mp_ping;
20563   int ret;
20564
20565   if (!vam->json_output)
20566     {
20567       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20568     }
20569
20570   M (L2_XCONNECT_DUMP, mp);
20571
20572   S (mp);
20573
20574   /* Use a control ping for synchronization */
20575   MPING (CONTROL_PING, mp_ping);
20576   S (mp_ping);
20577
20578   W (ret);
20579   return ret;
20580 }
20581
20582 static int
20583 api_sw_interface_set_mtu (vat_main_t * vam)
20584 {
20585   unformat_input_t *i = vam->input;
20586   vl_api_sw_interface_set_mtu_t *mp;
20587   u32 sw_if_index = ~0;
20588   u32 mtu = 0;
20589   int ret;
20590
20591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20592     {
20593       if (unformat (i, "mtu %d", &mtu))
20594         ;
20595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20596         ;
20597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20598         ;
20599       else
20600         break;
20601     }
20602
20603   if (sw_if_index == ~0)
20604     {
20605       errmsg ("missing interface name or sw_if_index");
20606       return -99;
20607     }
20608
20609   if (mtu == 0)
20610     {
20611       errmsg ("no mtu specified");
20612       return -99;
20613     }
20614
20615   /* Construct the API message */
20616   M (SW_INTERFACE_SET_MTU, mp);
20617   mp->sw_if_index = ntohl (sw_if_index);
20618   mp->mtu = ntohs ((u16) mtu);
20619
20620   S (mp);
20621   W (ret);
20622   return ret;
20623 }
20624
20625 static int
20626 api_p2p_ethernet_add (vat_main_t * vam)
20627 {
20628   unformat_input_t *i = vam->input;
20629   vl_api_p2p_ethernet_add_t *mp;
20630   u32 parent_if_index = ~0;
20631   u32 sub_id = ~0;
20632   u8 remote_mac[6];
20633   u8 mac_set = 0;
20634   int ret;
20635
20636   memset (remote_mac, 0, sizeof (remote_mac));
20637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20638     {
20639       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20640         ;
20641       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20642         ;
20643       else
20644         if (unformat
20645             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20646         mac_set++;
20647       else if (unformat (i, "sub_id %d", &sub_id))
20648         ;
20649       else
20650         {
20651           clib_warning ("parse error '%U'", format_unformat_error, i);
20652           return -99;
20653         }
20654     }
20655
20656   if (parent_if_index == ~0)
20657     {
20658       errmsg ("missing interface name or sw_if_index");
20659       return -99;
20660     }
20661   if (mac_set == 0)
20662     {
20663       errmsg ("missing remote mac address");
20664       return -99;
20665     }
20666   if (sub_id == ~0)
20667     {
20668       errmsg ("missing sub-interface id");
20669       return -99;
20670     }
20671
20672   M (P2P_ETHERNET_ADD, mp);
20673   mp->parent_if_index = ntohl (parent_if_index);
20674   mp->subif_id = ntohl (sub_id);
20675   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20676
20677   S (mp);
20678   W (ret);
20679   return ret;
20680 }
20681
20682 static int
20683 api_p2p_ethernet_del (vat_main_t * vam)
20684 {
20685   unformat_input_t *i = vam->input;
20686   vl_api_p2p_ethernet_del_t *mp;
20687   u32 parent_if_index = ~0;
20688   u8 remote_mac[6];
20689   u8 mac_set = 0;
20690   int ret;
20691
20692   memset (remote_mac, 0, sizeof (remote_mac));
20693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20694     {
20695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20696         ;
20697       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20698         ;
20699       else
20700         if (unformat
20701             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20702         mac_set++;
20703       else
20704         {
20705           clib_warning ("parse error '%U'", format_unformat_error, i);
20706           return -99;
20707         }
20708     }
20709
20710   if (parent_if_index == ~0)
20711     {
20712       errmsg ("missing interface name or sw_if_index");
20713       return -99;
20714     }
20715   if (mac_set == 0)
20716     {
20717       errmsg ("missing remote mac address");
20718       return -99;
20719     }
20720
20721   M (P2P_ETHERNET_DEL, mp);
20722   mp->parent_if_index = ntohl (parent_if_index);
20723   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20724
20725   S (mp);
20726   W (ret);
20727   return ret;
20728 }
20729
20730 static int
20731 api_lldp_config (vat_main_t * vam)
20732 {
20733   unformat_input_t *i = vam->input;
20734   vl_api_lldp_config_t *mp;
20735   int tx_hold = 0;
20736   int tx_interval = 0;
20737   u8 *sys_name = NULL;
20738   int ret;
20739
20740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20741     {
20742       if (unformat (i, "system-name %s", &sys_name))
20743         ;
20744       else if (unformat (i, "tx-hold %d", &tx_hold))
20745         ;
20746       else if (unformat (i, "tx-interval %d", &tx_interval))
20747         ;
20748       else
20749         {
20750           clib_warning ("parse error '%U'", format_unformat_error, i);
20751           return -99;
20752         }
20753     }
20754
20755   vec_add1 (sys_name, 0);
20756
20757   M (LLDP_CONFIG, mp);
20758   mp->tx_hold = htonl (tx_hold);
20759   mp->tx_interval = htonl (tx_interval);
20760   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20761   vec_free (sys_name);
20762
20763   S (mp);
20764   W (ret);
20765   return ret;
20766 }
20767
20768 static int
20769 api_sw_interface_set_lldp (vat_main_t * vam)
20770 {
20771   unformat_input_t *i = vam->input;
20772   vl_api_sw_interface_set_lldp_t *mp;
20773   u32 sw_if_index = ~0;
20774   u32 enable = 1;
20775   u8 *port_desc = NULL, *mgmt_oid = NULL;
20776   ip4_address_t ip4_addr;
20777   ip6_address_t ip6_addr;
20778   int ret;
20779
20780   memset (&ip4_addr, 0, sizeof (ip4_addr));
20781   memset (&ip6_addr, 0, sizeof (ip6_addr));
20782
20783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20784     {
20785       if (unformat (i, "disable"))
20786         enable = 0;
20787       else
20788         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20789         ;
20790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20791         ;
20792       else if (unformat (i, "port-desc %s", &port_desc))
20793         ;
20794       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20795         ;
20796       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20797         ;
20798       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20799         ;
20800       else
20801         break;
20802     }
20803
20804   if (sw_if_index == ~0)
20805     {
20806       errmsg ("missing interface name or sw_if_index");
20807       return -99;
20808     }
20809
20810   /* Construct the API message */
20811   vec_add1 (port_desc, 0);
20812   vec_add1 (mgmt_oid, 0);
20813   M (SW_INTERFACE_SET_LLDP, mp);
20814   mp->sw_if_index = ntohl (sw_if_index);
20815   mp->enable = enable;
20816   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20817   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20818   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20819   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20820   vec_free (port_desc);
20821   vec_free (mgmt_oid);
20822
20823   S (mp);
20824   W (ret);
20825   return ret;
20826 }
20827
20828 static int
20829 api_tcp_configure_src_addresses (vat_main_t * vam)
20830 {
20831   vl_api_tcp_configure_src_addresses_t *mp;
20832   unformat_input_t *i = vam->input;
20833   ip4_address_t v4first, v4last;
20834   ip6_address_t v6first, v6last;
20835   u8 range_set = 0;
20836   u32 vrf_id = 0;
20837   int ret;
20838
20839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20840     {
20841       if (unformat (i, "%U - %U",
20842                     unformat_ip4_address, &v4first,
20843                     unformat_ip4_address, &v4last))
20844         {
20845           if (range_set)
20846             {
20847               errmsg ("one range per message (range already set)");
20848               return -99;
20849             }
20850           range_set = 1;
20851         }
20852       else if (unformat (i, "%U - %U",
20853                          unformat_ip6_address, &v6first,
20854                          unformat_ip6_address, &v6last))
20855         {
20856           if (range_set)
20857             {
20858               errmsg ("one range per message (range already set)");
20859               return -99;
20860             }
20861           range_set = 2;
20862         }
20863       else if (unformat (i, "vrf %d", &vrf_id))
20864         ;
20865       else
20866         break;
20867     }
20868
20869   if (range_set == 0)
20870     {
20871       errmsg ("address range not set");
20872       return -99;
20873     }
20874
20875   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20876   mp->vrf_id = ntohl (vrf_id);
20877   /* ipv6? */
20878   if (range_set == 2)
20879     {
20880       mp->is_ipv6 = 1;
20881       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20882       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20883     }
20884   else
20885     {
20886       mp->is_ipv6 = 0;
20887       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20888       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20889     }
20890   S (mp);
20891   W (ret);
20892   return ret;
20893 }
20894
20895 static int
20896 api_app_namespace_add_del (vat_main_t * vam)
20897 {
20898   vl_api_app_namespace_add_del_t *mp;
20899   unformat_input_t *i = vam->input;
20900   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20901   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20902   u64 secret;
20903   int ret;
20904
20905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20906     {
20907       if (unformat (i, "id %_%v%_", &ns_id))
20908         ;
20909       else if (unformat (i, "secret %lu", &secret))
20910         secret_set = 1;
20911       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20912         sw_if_index_set = 1;
20913       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20914         ;
20915       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20916         ;
20917       else
20918         break;
20919     }
20920   if (!ns_id || !secret_set || !sw_if_index_set)
20921     {
20922       errmsg ("namespace id, secret and sw_if_index must be set");
20923       return -99;
20924     }
20925   if (vec_len (ns_id) > 64)
20926     {
20927       errmsg ("namespace id too long");
20928       return -99;
20929     }
20930   M (APP_NAMESPACE_ADD_DEL, mp);
20931
20932   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20933   mp->namespace_id_len = vec_len (ns_id);
20934   mp->secret = secret;
20935   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20936   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20937   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20938   vec_free (ns_id);
20939   S (mp);
20940   W (ret);
20941   return ret;
20942 }
20943
20944 static int
20945 api_memfd_segment_create (vat_main_t * vam)
20946 {
20947 #if VPP_API_TEST_BUILTIN == 0
20948   unformat_input_t *i = vam->input;
20949   vl_api_memfd_segment_create_t *mp;
20950   u64 size = 64 << 20;
20951   int ret;
20952
20953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20954     {
20955       if (unformat (i, "size %U", unformat_memory_size, &size))
20956         ;
20957       else
20958         break;
20959     }
20960
20961   M (MEMFD_SEGMENT_CREATE, mp);
20962   mp->requested_size = size;
20963   S (mp);
20964   W (ret);
20965   return ret;
20966
20967 #else
20968   errmsg ("memfd_segment_create (builtin) not supported");
20969   return -99;
20970 #endif
20971 }
20972
20973 static int
20974 api_dns_enable_disable (vat_main_t * vam)
20975 {
20976   unformat_input_t *line_input = vam->input;
20977   vl_api_dns_enable_disable_t *mp;
20978   u8 enable_disable = 1;
20979   int ret;
20980
20981   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20982     {
20983       if (unformat (line_input, "disable"))
20984         enable_disable = 0;
20985       if (unformat (line_input, "enable"))
20986         enable_disable = 1;
20987       else
20988         break;
20989     }
20990
20991   /* Construct the API message */
20992   M (DNS_ENABLE_DISABLE, mp);
20993   mp->enable = enable_disable;
20994
20995   /* send it... */
20996   S (mp);
20997   /* Wait for the reply */
20998   W (ret);
20999   return ret;
21000 }
21001
21002 static int
21003 api_dns_resolve_name (vat_main_t * vam)
21004 {
21005   unformat_input_t *line_input = vam->input;
21006   vl_api_dns_resolve_name_t *mp;
21007   u8 *name = 0;
21008   int ret;
21009
21010   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21011     {
21012       if (unformat (line_input, "%s", &name))
21013         ;
21014       else
21015         break;
21016     }
21017
21018   if (vec_len (name) > 127)
21019     {
21020       errmsg ("name too long");
21021       return -99;
21022     }
21023
21024   /* Construct the API message */
21025   M (DNS_RESOLVE_NAME, mp);
21026   memcpy (mp->name, name, vec_len (name));
21027   vec_free (name);
21028
21029   /* send it... */
21030   S (mp);
21031   /* Wait for the reply */
21032   W (ret);
21033   return ret;
21034 }
21035
21036 static int
21037 api_dns_resolve_ip (vat_main_t * vam)
21038 {
21039   unformat_input_t *line_input = vam->input;
21040   vl_api_dns_resolve_ip_t *mp;
21041   int is_ip6 = -1;
21042   ip4_address_t addr4;
21043   ip6_address_t addr6;
21044   int ret;
21045
21046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21047     {
21048       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21049         is_ip6 = 1;
21050       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21051         is_ip6 = 0;
21052       else
21053         break;
21054     }
21055
21056   if (is_ip6 == -1)
21057     {
21058       errmsg ("missing address");
21059       return -99;
21060     }
21061
21062   /* Construct the API message */
21063   M (DNS_RESOLVE_IP, mp);
21064   mp->is_ip6 = is_ip6;
21065   if (is_ip6)
21066     memcpy (mp->address, &addr6, sizeof (addr6));
21067   else
21068     memcpy (mp->address, &addr4, sizeof (addr4));
21069
21070   /* send it... */
21071   S (mp);
21072   /* Wait for the reply */
21073   W (ret);
21074   return ret;
21075 }
21076
21077 static int
21078 api_dns_name_server_add_del (vat_main_t * vam)
21079 {
21080   unformat_input_t *i = vam->input;
21081   vl_api_dns_name_server_add_del_t *mp;
21082   u8 is_add = 1;
21083   ip6_address_t ip6_server;
21084   ip4_address_t ip4_server;
21085   int ip6_set = 0;
21086   int ip4_set = 0;
21087   int ret = 0;
21088
21089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21090     {
21091       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21092         ip6_set = 1;
21093       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21094         ip4_set = 1;
21095       else if (unformat (i, "del"))
21096         is_add = 0;
21097       else
21098         {
21099           clib_warning ("parse error '%U'", format_unformat_error, i);
21100           return -99;
21101         }
21102     }
21103
21104   if (ip4_set && ip6_set)
21105     {
21106       errmsg ("Only one server address allowed per message");
21107       return -99;
21108     }
21109   if ((ip4_set + ip6_set) == 0)
21110     {
21111       errmsg ("Server address required");
21112       return -99;
21113     }
21114
21115   /* Construct the API message */
21116   M (DNS_NAME_SERVER_ADD_DEL, mp);
21117
21118   if (ip6_set)
21119     {
21120       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21121       mp->is_ip6 = 1;
21122     }
21123   else
21124     {
21125       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21126       mp->is_ip6 = 0;
21127     }
21128
21129   mp->is_add = is_add;
21130
21131   /* send it... */
21132   S (mp);
21133
21134   /* Wait for a reply, return good/bad news  */
21135   W (ret);
21136   return ret;
21137 }
21138
21139
21140 static int
21141 q_or_quit (vat_main_t * vam)
21142 {
21143 #if VPP_API_TEST_BUILTIN == 0
21144   longjmp (vam->jump_buf, 1);
21145 #endif
21146   return 0;                     /* not so much */
21147 }
21148
21149 static int
21150 q (vat_main_t * vam)
21151 {
21152   return q_or_quit (vam);
21153 }
21154
21155 static int
21156 quit (vat_main_t * vam)
21157 {
21158   return q_or_quit (vam);
21159 }
21160
21161 static int
21162 comment (vat_main_t * vam)
21163 {
21164   return 0;
21165 }
21166
21167 static int
21168 cmd_cmp (void *a1, void *a2)
21169 {
21170   u8 **c1 = a1;
21171   u8 **c2 = a2;
21172
21173   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21174 }
21175
21176 static int
21177 help (vat_main_t * vam)
21178 {
21179   u8 **cmds = 0;
21180   u8 *name = 0;
21181   hash_pair_t *p;
21182   unformat_input_t *i = vam->input;
21183   int j;
21184
21185   if (unformat (i, "%s", &name))
21186     {
21187       uword *hs;
21188
21189       vec_add1 (name, 0);
21190
21191       hs = hash_get_mem (vam->help_by_name, name);
21192       if (hs)
21193         print (vam->ofp, "usage: %s %s", name, hs[0]);
21194       else
21195         print (vam->ofp, "No such msg / command '%s'", name);
21196       vec_free (name);
21197       return 0;
21198     }
21199
21200   print (vam->ofp, "Help is available for the following:");
21201
21202     /* *INDENT-OFF* */
21203     hash_foreach_pair (p, vam->function_by_name,
21204     ({
21205       vec_add1 (cmds, (u8 *)(p->key));
21206     }));
21207     /* *INDENT-ON* */
21208
21209   vec_sort_with_function (cmds, cmd_cmp);
21210
21211   for (j = 0; j < vec_len (cmds); j++)
21212     print (vam->ofp, "%s", cmds[j]);
21213
21214   vec_free (cmds);
21215   return 0;
21216 }
21217
21218 static int
21219 set (vat_main_t * vam)
21220 {
21221   u8 *name = 0, *value = 0;
21222   unformat_input_t *i = vam->input;
21223
21224   if (unformat (i, "%s", &name))
21225     {
21226       /* The input buffer is a vector, not a string. */
21227       value = vec_dup (i->buffer);
21228       vec_delete (value, i->index, 0);
21229       /* Almost certainly has a trailing newline */
21230       if (value[vec_len (value) - 1] == '\n')
21231         value[vec_len (value) - 1] = 0;
21232       /* Make sure it's a proper string, one way or the other */
21233       vec_add1 (value, 0);
21234       (void) clib_macro_set_value (&vam->macro_main,
21235                                    (char *) name, (char *) value);
21236     }
21237   else
21238     errmsg ("usage: set <name> <value>");
21239
21240   vec_free (name);
21241   vec_free (value);
21242   return 0;
21243 }
21244
21245 static int
21246 unset (vat_main_t * vam)
21247 {
21248   u8 *name = 0;
21249
21250   if (unformat (vam->input, "%s", &name))
21251     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21252       errmsg ("unset: %s wasn't set", name);
21253   vec_free (name);
21254   return 0;
21255 }
21256
21257 typedef struct
21258 {
21259   u8 *name;
21260   u8 *value;
21261 } macro_sort_t;
21262
21263
21264 static int
21265 macro_sort_cmp (void *a1, void *a2)
21266 {
21267   macro_sort_t *s1 = a1;
21268   macro_sort_t *s2 = a2;
21269
21270   return strcmp ((char *) (s1->name), (char *) (s2->name));
21271 }
21272
21273 static int
21274 dump_macro_table (vat_main_t * vam)
21275 {
21276   macro_sort_t *sort_me = 0, *sm;
21277   int i;
21278   hash_pair_t *p;
21279
21280     /* *INDENT-OFF* */
21281     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21282     ({
21283       vec_add2 (sort_me, sm, 1);
21284       sm->name = (u8 *)(p->key);
21285       sm->value = (u8 *) (p->value[0]);
21286     }));
21287     /* *INDENT-ON* */
21288
21289   vec_sort_with_function (sort_me, macro_sort_cmp);
21290
21291   if (vec_len (sort_me))
21292     print (vam->ofp, "%-15s%s", "Name", "Value");
21293   else
21294     print (vam->ofp, "The macro table is empty...");
21295
21296   for (i = 0; i < vec_len (sort_me); i++)
21297     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21298   return 0;
21299 }
21300
21301 static int
21302 dump_node_table (vat_main_t * vam)
21303 {
21304   int i, j;
21305   vlib_node_t *node, *next_node;
21306
21307   if (vec_len (vam->graph_nodes) == 0)
21308     {
21309       print (vam->ofp, "Node table empty, issue get_node_graph...");
21310       return 0;
21311     }
21312
21313   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21314     {
21315       node = vam->graph_nodes[i];
21316       print (vam->ofp, "[%d] %s", i, node->name);
21317       for (j = 0; j < vec_len (node->next_nodes); j++)
21318         {
21319           if (node->next_nodes[j] != ~0)
21320             {
21321               next_node = vam->graph_nodes[node->next_nodes[j]];
21322               print (vam->ofp, "  [%d] %s", j, next_node->name);
21323             }
21324         }
21325     }
21326   return 0;
21327 }
21328
21329 static int
21330 value_sort_cmp (void *a1, void *a2)
21331 {
21332   name_sort_t *n1 = a1;
21333   name_sort_t *n2 = a2;
21334
21335   if (n1->value < n2->value)
21336     return -1;
21337   if (n1->value > n2->value)
21338     return 1;
21339   return 0;
21340 }
21341
21342
21343 static int
21344 dump_msg_api_table (vat_main_t * vam)
21345 {
21346   api_main_t *am = &api_main;
21347   name_sort_t *nses = 0, *ns;
21348   hash_pair_t *hp;
21349   int i;
21350
21351   /* *INDENT-OFF* */
21352   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21353   ({
21354     vec_add2 (nses, ns, 1);
21355     ns->name = (u8 *)(hp->key);
21356     ns->value = (u32) hp->value[0];
21357   }));
21358   /* *INDENT-ON* */
21359
21360   vec_sort_with_function (nses, value_sort_cmp);
21361
21362   for (i = 0; i < vec_len (nses); i++)
21363     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21364   vec_free (nses);
21365   return 0;
21366 }
21367
21368 static int
21369 get_msg_id (vat_main_t * vam)
21370 {
21371   u8 *name_and_crc;
21372   u32 message_index;
21373
21374   if (unformat (vam->input, "%s", &name_and_crc))
21375     {
21376       message_index = vl_api_get_msg_index (name_and_crc);
21377       if (message_index == ~0)
21378         {
21379           print (vam->ofp, " '%s' not found", name_and_crc);
21380           return 0;
21381         }
21382       print (vam->ofp, " '%s' has message index %d",
21383              name_and_crc, message_index);
21384       return 0;
21385     }
21386   errmsg ("name_and_crc required...");
21387   return 0;
21388 }
21389
21390 static int
21391 search_node_table (vat_main_t * vam)
21392 {
21393   unformat_input_t *line_input = vam->input;
21394   u8 *node_to_find;
21395   int j;
21396   vlib_node_t *node, *next_node;
21397   uword *p;
21398
21399   if (vam->graph_node_index_by_name == 0)
21400     {
21401       print (vam->ofp, "Node table empty, issue get_node_graph...");
21402       return 0;
21403     }
21404
21405   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21406     {
21407       if (unformat (line_input, "%s", &node_to_find))
21408         {
21409           vec_add1 (node_to_find, 0);
21410           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21411           if (p == 0)
21412             {
21413               print (vam->ofp, "%s not found...", node_to_find);
21414               goto out;
21415             }
21416           node = vam->graph_nodes[p[0]];
21417           print (vam->ofp, "[%d] %s", p[0], node->name);
21418           for (j = 0; j < vec_len (node->next_nodes); j++)
21419             {
21420               if (node->next_nodes[j] != ~0)
21421                 {
21422                   next_node = vam->graph_nodes[node->next_nodes[j]];
21423                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21424                 }
21425             }
21426         }
21427
21428       else
21429         {
21430           clib_warning ("parse error '%U'", format_unformat_error,
21431                         line_input);
21432           return -99;
21433         }
21434
21435     out:
21436       vec_free (node_to_find);
21437
21438     }
21439
21440   return 0;
21441 }
21442
21443
21444 static int
21445 script (vat_main_t * vam)
21446 {
21447 #if (VPP_API_TEST_BUILTIN==0)
21448   u8 *s = 0;
21449   char *save_current_file;
21450   unformat_input_t save_input;
21451   jmp_buf save_jump_buf;
21452   u32 save_line_number;
21453
21454   FILE *new_fp, *save_ifp;
21455
21456   if (unformat (vam->input, "%s", &s))
21457     {
21458       new_fp = fopen ((char *) s, "r");
21459       if (new_fp == 0)
21460         {
21461           errmsg ("Couldn't open script file %s", s);
21462           vec_free (s);
21463           return -99;
21464         }
21465     }
21466   else
21467     {
21468       errmsg ("Missing script name");
21469       return -99;
21470     }
21471
21472   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21473   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21474   save_ifp = vam->ifp;
21475   save_line_number = vam->input_line_number;
21476   save_current_file = (char *) vam->current_file;
21477
21478   vam->input_line_number = 0;
21479   vam->ifp = new_fp;
21480   vam->current_file = s;
21481   do_one_file (vam);
21482
21483   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21484   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21485   vam->ifp = save_ifp;
21486   vam->input_line_number = save_line_number;
21487   vam->current_file = (u8 *) save_current_file;
21488   vec_free (s);
21489
21490   return 0;
21491 #else
21492   clib_warning ("use the exec command...");
21493   return -99;
21494 #endif
21495 }
21496
21497 static int
21498 echo (vat_main_t * vam)
21499 {
21500   print (vam->ofp, "%v", vam->input->buffer);
21501   return 0;
21502 }
21503
21504 /* List of API message constructors, CLI names map to api_xxx */
21505 #define foreach_vpe_api_msg                                             \
21506 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21507 _(sw_interface_dump,"")                                                 \
21508 _(sw_interface_set_flags,                                               \
21509   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21510 _(sw_interface_add_del_address,                                         \
21511   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21512 _(sw_interface_set_table,                                               \
21513   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21514 _(sw_interface_set_mpls_enable,                                         \
21515   "<intfc> | sw_if_index [disable | dis]")                              \
21516 _(sw_interface_set_vpath,                                               \
21517   "<intfc> | sw_if_index <id> enable | disable")                        \
21518 _(sw_interface_set_vxlan_bypass,                                        \
21519   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21520 _(sw_interface_set_geneve_bypass,                                       \
21521   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21522 _(sw_interface_set_l2_xconnect,                                         \
21523   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21524   "enable | disable")                                                   \
21525 _(sw_interface_set_l2_bridge,                                           \
21526   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21527   "[shg <split-horizon-group>] [bvi]\n"                                 \
21528   "enable | disable")                                                   \
21529 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21530 _(bridge_domain_add_del,                                                \
21531   "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") \
21532 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21533 _(l2fib_add_del,                                                        \
21534   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21535 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21536 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21537 _(l2_flags,                                                             \
21538   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21539 _(bridge_flags,                                                         \
21540   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21541 _(tap_connect,                                                          \
21542   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21543 _(tap_modify,                                                           \
21544   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21545 _(tap_delete,                                                           \
21546   "<vpp-if-name> | sw_if_index <id>")                                   \
21547 _(sw_interface_tap_dump, "")                                            \
21548 _(ip_table_add_del,                                                     \
21549   "table-id <n> [ipv6]\n")                                              \
21550 _(ip_add_del_route,                                                     \
21551   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21552   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21553   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21554   "[multipath] [count <n>]")                                            \
21555 _(ip_mroute_add_del,                                                    \
21556   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21557   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21558 _(mpls_table_add_del,                                                   \
21559   "table-id <n>\n")                                                     \
21560 _(mpls_route_add_del,                                                   \
21561   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21562   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21563   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21564   "[multipath] [count <n>]")                                            \
21565 _(mpls_ip_bind_unbind,                                                  \
21566   "<label> <addr/len>")                                                 \
21567 _(mpls_tunnel_add_del,                                                  \
21568   " via <addr> [table-id <n>]\n"                                        \
21569   "sw_if_index <id>] [l2]  [del]")                                      \
21570 _(proxy_arp_add_del,                                                    \
21571   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21572 _(proxy_arp_intfc_enable_disable,                                       \
21573   "<intfc> | sw_if_index <id> enable | disable")                        \
21574 _(sw_interface_set_unnumbered,                                          \
21575   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21576 _(ip_neighbor_add_del,                                                  \
21577   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21578   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21579 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21580 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21581 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21582   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21583   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21584   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21585 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21586 _(reset_fib, "vrf <n> [ipv6]")                                          \
21587 _(dhcp_proxy_config,                                                    \
21588   "svr <v46-address> src <v46-address>\n"                               \
21589    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21590 _(dhcp_proxy_set_vss,                                                   \
21591   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21592 _(dhcp_proxy_dump, "ip6")                                               \
21593 _(dhcp_client_config,                                                   \
21594   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21595 _(set_ip_flow_hash,                                                     \
21596   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21597 _(sw_interface_ip6_enable_disable,                                      \
21598   "<intfc> | sw_if_index <id> enable | disable")                        \
21599 _(sw_interface_ip6_set_link_local_address,                              \
21600   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21601 _(ip6nd_proxy_add_del,                                                  \
21602   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21603 _(ip6nd_proxy_dump, "")                                                 \
21604 _(sw_interface_ip6nd_ra_prefix,                                         \
21605   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21606   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21607   "[nolink] [isno]")                                                    \
21608 _(sw_interface_ip6nd_ra_config,                                         \
21609   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21610   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21611   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21612 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21613 _(l2_patch_add_del,                                                     \
21614   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21615   "enable | disable")                                                   \
21616 _(sr_localsid_add_del,                                                  \
21617   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21618   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21619 _(classify_add_del_table,                                               \
21620   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21621   " [del] [del-chain] mask <mask-value>\n"                              \
21622   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21623   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21624 _(classify_add_del_session,                                             \
21625   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21626   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21627   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21628   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21629 _(classify_set_interface_ip_table,                                      \
21630   "<intfc> | sw_if_index <nn> table <nn>")                              \
21631 _(classify_set_interface_l2_tables,                                     \
21632   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21633   "  [other-table <nn>]")                                               \
21634 _(get_node_index, "node <node-name")                                    \
21635 _(add_node_next, "node <node-name> next <next-node-name>")              \
21636 _(l2tpv3_create_tunnel,                                                 \
21637   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21638   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21639   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21640 _(l2tpv3_set_tunnel_cookies,                                            \
21641   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21642   "[new_remote_cookie <nn>]\n")                                         \
21643 _(l2tpv3_interface_enable_disable,                                      \
21644   "<intfc> | sw_if_index <nn> enable | disable")                        \
21645 _(l2tpv3_set_lookup_key,                                                \
21646   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21647 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21648 _(vxlan_add_del_tunnel,                                                 \
21649   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21650   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21651   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21652 _(geneve_add_del_tunnel,                                                \
21653   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21654   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21655   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21656 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21657 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21658 _(gre_add_del_tunnel,                                                   \
21659   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21660 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21661 _(l2_fib_clear_table, "")                                               \
21662 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21663 _(l2_interface_vlan_tag_rewrite,                                        \
21664   "<intfc> | sw_if_index <nn> \n"                                       \
21665   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21666   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21667 _(create_vhost_user_if,                                                 \
21668         "socket <filename> [server] [renumber <dev_instance>] "         \
21669         "[mac <mac_address>]")                                          \
21670 _(modify_vhost_user_if,                                                 \
21671         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21672         "[server] [renumber <dev_instance>]")                           \
21673 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21674 _(sw_interface_vhost_user_dump, "")                                     \
21675 _(show_version, "")                                                     \
21676 _(vxlan_gpe_add_del_tunnel,                                             \
21677   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21678   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21679   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21680   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21681 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21682 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21683 _(interface_name_renumber,                                              \
21684   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21685 _(input_acl_set_interface,                                              \
21686   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21687   "  [l2-table <nn>] [del]")                                            \
21688 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21689 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21690 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21691 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21692 _(ip_dump, "ipv4 | ipv6")                                               \
21693 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21694 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21695   "  spid_id <n> ")                                                     \
21696 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21697   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21698   "  integ_alg <alg> integ_key <hex>")                                  \
21699 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21700   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21701   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21702   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21703 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21704 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21705   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21706   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21707   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21708 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21709 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21710   "  <alg> <hex>\n")                                                    \
21711 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21712 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21713   "(auth_data 0x<data> | auth_data <data>)")                            \
21714 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21715   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21716 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21717   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21718   "(local|remote)")                                                     \
21719 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21720 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21721 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21722 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21723 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21724 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21725 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21726 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21727 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21728 _(delete_loopback,"sw_if_index <nn>")                                   \
21729 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21730 _(map_add_domain,                                                       \
21731   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21732   "ip6-src <ip6addr> "                                                  \
21733   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21734 _(map_del_domain, "index <n>")                                          \
21735 _(map_add_del_rule,                                                     \
21736   "index <n> psid <n> dst <ip6addr> [del]")                             \
21737 _(map_domain_dump, "")                                                  \
21738 _(map_rule_dump, "index <map-domain>")                                  \
21739 _(want_interface_events,  "enable|disable")                             \
21740 _(want_stats,"enable|disable")                                          \
21741 _(get_first_msg_id, "client <name>")                                    \
21742 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21743 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21744   "fib-id <nn> [ip4][ip6][default]")                                    \
21745 _(get_node_graph, " ")                                                  \
21746 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21747 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21748 _(ioam_disable, "")                                                     \
21749 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21750                             " sw_if_index <sw_if_index> p <priority> "  \
21751                             "w <weight>] [del]")                        \
21752 _(one_add_del_locator, "locator-set <locator_name> "                    \
21753                         "iface <intf> | sw_if_index <sw_if_index> "     \
21754                         "p <priority> w <weight> [del]")                \
21755 _(one_add_del_local_eid,"vni <vni> eid "                                \
21756                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21757                          "locator-set <locator_name> [del]"             \
21758                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21759 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21760 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21761 _(one_enable_disable, "enable|disable")                                 \
21762 _(one_map_register_enable_disable, "enable|disable")                    \
21763 _(one_map_register_fallback_threshold, "<value>")                       \
21764 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21765 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21766                                "[seid <seid>] "                         \
21767                                "rloc <locator> p <prio> "               \
21768                                "w <weight> [rloc <loc> ... ] "          \
21769                                "action <action> [del-all]")             \
21770 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21771                           "<local-eid>")                                \
21772 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21773 _(one_use_petr, "ip-address> | disable")                                \
21774 _(one_map_request_mode, "src-dst|dst-only")                             \
21775 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21776 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21777 _(one_locator_set_dump, "[local | remote]")                             \
21778 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21779 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21780                        "[local] | [remote]")                            \
21781 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21782 _(one_ndp_bd_get, "")                                                   \
21783 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21784 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21785 _(one_l2_arp_bd_get, "")                                                \
21786 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21787 _(one_stats_enable_disable, "enable|disalbe")                           \
21788 _(show_one_stats_enable_disable, "")                                    \
21789 _(one_eid_table_vni_dump, "")                                           \
21790 _(one_eid_table_map_dump, "l2|l3")                                      \
21791 _(one_map_resolver_dump, "")                                            \
21792 _(one_map_server_dump, "")                                              \
21793 _(one_adjacencies_get, "vni <vni>")                                     \
21794 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21795 _(show_one_rloc_probe_state, "")                                        \
21796 _(show_one_map_register_state, "")                                      \
21797 _(show_one_status, "")                                                  \
21798 _(one_stats_dump, "")                                                   \
21799 _(one_stats_flush, "")                                                  \
21800 _(one_get_map_request_itr_rlocs, "")                                    \
21801 _(one_map_register_set_ttl, "<ttl>")                                    \
21802 _(one_set_transport_protocol, "udp|api")                                \
21803 _(one_get_transport_protocol, "")                                       \
21804 _(show_one_nsh_mapping, "")                                             \
21805 _(show_one_pitr, "")                                                    \
21806 _(show_one_use_petr, "")                                                \
21807 _(show_one_map_request_mode, "")                                        \
21808 _(show_one_map_register_ttl, "")                                        \
21809 _(show_one_map_register_fallback_threshold, "")                         \
21810 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21811                             " sw_if_index <sw_if_index> p <priority> "  \
21812                             "w <weight>] [del]")                        \
21813 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21814                         "iface <intf> | sw_if_index <sw_if_index> "     \
21815                         "p <priority> w <weight> [del]")                \
21816 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21817                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21818                          "locator-set <locator_name> [del]"             \
21819                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21820 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21821 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21822 _(lisp_enable_disable, "enable|disable")                                \
21823 _(lisp_map_register_enable_disable, "enable|disable")                   \
21824 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21825 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21826                                "[seid <seid>] "                         \
21827                                "rloc <locator> p <prio> "               \
21828                                "w <weight> [rloc <loc> ... ] "          \
21829                                "action <action> [del-all]")             \
21830 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21831                           "<local-eid>")                                \
21832 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21833 _(lisp_use_petr, "<ip-address> | disable")                              \
21834 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21835 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21836 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21837 _(lisp_locator_set_dump, "[local | remote]")                            \
21838 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21839 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21840                        "[local] | [remote]")                            \
21841 _(lisp_eid_table_vni_dump, "")                                          \
21842 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21843 _(lisp_map_resolver_dump, "")                                           \
21844 _(lisp_map_server_dump, "")                                             \
21845 _(lisp_adjacencies_get, "vni <vni>")                                    \
21846 _(gpe_fwd_entry_vnis_get, "")                                           \
21847 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21848 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21849                                 "[table <table-id>]")                   \
21850 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21851 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21852 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21853 _(gpe_get_encap_mode, "")                                               \
21854 _(lisp_gpe_add_del_iface, "up|down")                                    \
21855 _(lisp_gpe_enable_disable, "enable|disable")                            \
21856 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21857   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21858 _(show_lisp_rloc_probe_state, "")                                       \
21859 _(show_lisp_map_register_state, "")                                     \
21860 _(show_lisp_status, "")                                                 \
21861 _(lisp_get_map_request_itr_rlocs, "")                                   \
21862 _(show_lisp_pitr, "")                                                   \
21863 _(show_lisp_use_petr, "")                                               \
21864 _(show_lisp_map_request_mode, "")                                       \
21865 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21866 _(af_packet_delete, "name <host interface name>")                       \
21867 _(policer_add_del, "name <policer name> <params> [del]")                \
21868 _(policer_dump, "[name <policer name>]")                                \
21869 _(policer_classify_set_interface,                                       \
21870   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21871   "  [l2-table <nn>] [del]")                                            \
21872 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21873 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21874     "[master|slave]")                                                   \
21875 _(netmap_delete, "name <interface name>")                               \
21876 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21877 _(mpls_fib_dump, "")                                                    \
21878 _(classify_table_ids, "")                                               \
21879 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21880 _(classify_table_info, "table_id <nn>")                                 \
21881 _(classify_session_dump, "table_id <nn>")                               \
21882 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21883     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21884     "[template_interval <nn>] [udp_checksum]")                          \
21885 _(ipfix_exporter_dump, "")                                              \
21886 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21887 _(ipfix_classify_stream_dump, "")                                       \
21888 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21889 _(ipfix_classify_table_dump, "")                                        \
21890 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21891 _(sw_interface_span_dump, "[l2]")                                           \
21892 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21893 _(pg_create_interface, "if_id <nn>")                                    \
21894 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21895 _(pg_enable_disable, "[stream <id>] disable")                           \
21896 _(ip_source_and_port_range_check_add_del,                               \
21897   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21898 _(ip_source_and_port_range_check_interface_add_del,                     \
21899   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21900   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21901 _(ipsec_gre_add_del_tunnel,                                             \
21902   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21903 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21904 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21905 _(l2_interface_pbb_tag_rewrite,                                         \
21906   "<intfc> | sw_if_index <nn> \n"                                       \
21907   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21908   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21909 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21910 _(flow_classify_set_interface,                                          \
21911   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21912 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21913 _(ip_fib_dump, "")                                                      \
21914 _(ip_mfib_dump, "")                                                     \
21915 _(ip6_fib_dump, "")                                                     \
21916 _(ip6_mfib_dump, "")                                                    \
21917 _(feature_enable_disable, "arc_name <arc_name> "                        \
21918   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21919 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21920 "[disable]")                                                            \
21921 _(l2_xconnect_dump, "")                                                 \
21922 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21923 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21924 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21925 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21926 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21927 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21928 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21929   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21930 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21931 _(memfd_segment_create,"size <nnn>")                                    \
21932 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21933 _(dns_enable_disable, "[enable][disable]")                              \
21934 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21935 _(dns_resolve_name, "<hostname>")                                       \
21936 _(dns_resolve_ip, "<ip4|ip6>")
21937
21938 /* List of command functions, CLI names map directly to functions */
21939 #define foreach_cli_function                                    \
21940 _(comment, "usage: comment <ignore-rest-of-line>")              \
21941 _(dump_interface_table, "usage: dump_interface_table")          \
21942 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21943 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21944 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21945 _(dump_stats_table, "usage: dump_stats_table")                  \
21946 _(dump_macro_table, "usage: dump_macro_table ")                 \
21947 _(dump_node_table, "usage: dump_node_table")                    \
21948 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21949 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21950 _(echo, "usage: echo <message>")                                \
21951 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21952 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21953 _(help, "usage: help")                                          \
21954 _(q, "usage: quit")                                             \
21955 _(quit, "usage: quit")                                          \
21956 _(search_node_table, "usage: search_node_table <name>...")      \
21957 _(set, "usage: set <variable-name> <value>")                    \
21958 _(script, "usage: script <file-name>")                          \
21959 _(unset, "usage: unset <variable-name>")
21960 #define _(N,n)                                  \
21961     static void vl_api_##n##_t_handler_uni      \
21962     (vl_api_##n##_t * mp)                       \
21963     {                                           \
21964         vat_main_t * vam = &vat_main;           \
21965         if (vam->json_output) {                 \
21966             vl_api_##n##_t_handler_json(mp);    \
21967         } else {                                \
21968             vl_api_##n##_t_handler(mp);         \
21969         }                                       \
21970     }
21971 foreach_vpe_api_reply_msg;
21972 #if VPP_API_TEST_BUILTIN == 0
21973 foreach_standalone_reply_msg;
21974 #endif
21975 #undef _
21976
21977 void
21978 vat_api_hookup (vat_main_t * vam)
21979 {
21980 #define _(N,n)                                                  \
21981     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21982                            vl_api_##n##_t_handler_uni,          \
21983                            vl_noop_handler,                     \
21984                            vl_api_##n##_t_endian,               \
21985                            vl_api_##n##_t_print,                \
21986                            sizeof(vl_api_##n##_t), 1);
21987   foreach_vpe_api_reply_msg;
21988 #if VPP_API_TEST_BUILTIN == 0
21989   foreach_standalone_reply_msg;
21990 #endif
21991 #undef _
21992
21993 #if (VPP_API_TEST_BUILTIN==0)
21994   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21995
21996   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21997
21998   vam->function_by_name = hash_create_string (0, sizeof (uword));
21999
22000   vam->help_by_name = hash_create_string (0, sizeof (uword));
22001 #endif
22002
22003   /* API messages we can send */
22004 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22005   foreach_vpe_api_msg;
22006 #undef _
22007
22008   /* Help strings */
22009 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22010   foreach_vpe_api_msg;
22011 #undef _
22012
22013   /* CLI functions */
22014 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22015   foreach_cli_function;
22016 #undef _
22017
22018   /* Help strings */
22019 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22020   foreach_cli_function;
22021 #undef _
22022 }
22023
22024 #if VPP_API_TEST_BUILTIN
22025 static clib_error_t *
22026 vat_api_hookup_shim (vlib_main_t * vm)
22027 {
22028   vat_api_hookup (&vat_main);
22029   return 0;
22030 }
22031
22032 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22033 #endif
22034
22035 /*
22036  * fd.io coding-style-patch-verification: ON
22037  *
22038  * Local Variables:
22039  * eval: (c-set-style "gnu")
22040  * End:
22041  */