Remove unused 'not_last' parameter from ip_add_del_route
[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 ("no");
2213 }
2214
2215 static void vl_api_ip_address_details_t_handler
2216   (vl_api_ip_address_details_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   static ip_address_details_t empty_ip_address_details = { {0} };
2220   ip_address_details_t *address = NULL;
2221   ip_details_t *current_ip_details = NULL;
2222   ip_details_t *details = NULL;
2223
2224   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2225
2226   if (!details || vam->current_sw_if_index >= vec_len (details)
2227       || !details[vam->current_sw_if_index].present)
2228     {
2229       errmsg ("ip address details arrived but not stored");
2230       errmsg ("ip_dump should be called first");
2231       return;
2232     }
2233
2234   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2235
2236 #define addresses (current_ip_details->addr)
2237
2238   vec_validate_init_empty (addresses, vec_len (addresses),
2239                            empty_ip_address_details);
2240
2241   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2242
2243   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2244   address->prefix_length = mp->prefix_length;
2245 #undef addresses
2246 }
2247
2248 static void vl_api_ip_address_details_t_handler_json
2249   (vl_api_ip_address_details_t * mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   vat_json_node_t *node = NULL;
2253   struct in6_addr ip6;
2254   struct in_addr ip4;
2255
2256   if (VAT_JSON_ARRAY != vam->json_tree.type)
2257     {
2258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2259       vat_json_init_array (&vam->json_tree);
2260     }
2261   node = vat_json_array_add (&vam->json_tree);
2262
2263   vat_json_init_object (node);
2264   if (vam->is_ipv6)
2265     {
2266       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2267       vat_json_object_add_ip6 (node, "ip", ip6);
2268     }
2269   else
2270     {
2271       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2272       vat_json_object_add_ip4 (node, "ip", ip4);
2273     }
2274   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2275 }
2276
2277 static void
2278 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   static ip_details_t empty_ip_details = { 0 };
2282   ip_details_t *ip = NULL;
2283   u32 sw_if_index = ~0;
2284
2285   sw_if_index = ntohl (mp->sw_if_index);
2286
2287   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2288                            sw_if_index, empty_ip_details);
2289
2290   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2291                          sw_if_index);
2292
2293   ip->present = 1;
2294 }
2295
2296 static void
2297 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2298 {
2299   vat_main_t *vam = &vat_main;
2300
2301   if (VAT_JSON_ARRAY != vam->json_tree.type)
2302     {
2303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2304       vat_json_init_array (&vam->json_tree);
2305     }
2306   vat_json_array_add_uint (&vam->json_tree,
2307                            clib_net_to_host_u32 (mp->sw_if_index));
2308 }
2309
2310 static void vl_api_map_domain_details_t_handler_json
2311   (vl_api_map_domain_details_t * mp)
2312 {
2313   vat_json_node_t *node = NULL;
2314   vat_main_t *vam = &vat_main;
2315   struct in6_addr ip6;
2316   struct in_addr ip4;
2317
2318   if (VAT_JSON_ARRAY != vam->json_tree.type)
2319     {
2320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2321       vat_json_init_array (&vam->json_tree);
2322     }
2323
2324   node = vat_json_array_add (&vam->json_tree);
2325   vat_json_init_object (node);
2326
2327   vat_json_object_add_uint (node, "domain_index",
2328                             clib_net_to_host_u32 (mp->domain_index));
2329   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2330   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2331   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2332   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2333   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2334   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2335   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2336   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2337   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2338   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2339   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2340   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2341   vat_json_object_add_uint (node, "flags", mp->flags);
2342   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2343   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2344 }
2345
2346 static void vl_api_map_domain_details_t_handler
2347   (vl_api_map_domain_details_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350
2351   if (mp->is_translation)
2352     {
2353       print (vam->ofp,
2354              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2355              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2356              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2357              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2358              clib_net_to_host_u32 (mp->domain_index));
2359     }
2360   else
2361     {
2362       print (vam->ofp,
2363              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2364              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2365              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2366              format_ip6_address, mp->ip6_src,
2367              clib_net_to_host_u32 (mp->domain_index));
2368     }
2369   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2370          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2371          mp->is_translation ? "map-t" : "");
2372 }
2373
2374 static void vl_api_map_rule_details_t_handler_json
2375   (vl_api_map_rule_details_t * mp)
2376 {
2377   struct in6_addr ip6;
2378   vat_json_node_t *node = NULL;
2379   vat_main_t *vam = &vat_main;
2380
2381   if (VAT_JSON_ARRAY != vam->json_tree.type)
2382     {
2383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2384       vat_json_init_array (&vam->json_tree);
2385     }
2386
2387   node = vat_json_array_add (&vam->json_tree);
2388   vat_json_init_object (node);
2389
2390   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2391   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2392   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2393 }
2394
2395 static void
2396 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2400          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2401 }
2402
2403 static void
2404 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2405 {
2406   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2407           "router_addr %U host_mac %U",
2408           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2409           format_ip4_address, &mp->host_address,
2410           format_ip4_address, &mp->router_address,
2411           format_ethernet_address, mp->host_mac);
2412 }
2413
2414 static void vl_api_dhcp_compl_event_t_handler_json
2415   (vl_api_dhcp_compl_event_t * mp)
2416 {
2417   /* JSON output not supported */
2418 }
2419
2420 static void
2421 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2422                               u32 counter)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   static u64 default_counter = 0;
2426
2427   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2428                            NULL);
2429   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2430                            sw_if_index, default_counter);
2431   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2432 }
2433
2434 static void
2435 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2436                                 interface_counter_t counter)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   static interface_counter_t default_counter = { 0, };
2440
2441   vec_validate_init_empty (vam->combined_interface_counters,
2442                            vnet_counter_type, NULL);
2443   vec_validate_init_empty (vam->combined_interface_counters
2444                            [vnet_counter_type], sw_if_index, default_counter);
2445   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2446 }
2447
2448 static void vl_api_vnet_interface_simple_counters_t_handler
2449   (vl_api_vnet_interface_simple_counters_t * mp)
2450 {
2451   /* not supported */
2452 }
2453
2454 static void vl_api_vnet_interface_combined_counters_t_handler
2455   (vl_api_vnet_interface_combined_counters_t * mp)
2456 {
2457   /* not supported */
2458 }
2459
2460 static void vl_api_vnet_interface_simple_counters_t_handler_json
2461   (vl_api_vnet_interface_simple_counters_t * mp)
2462 {
2463   u64 *v_packets;
2464   u64 packets;
2465   u32 count;
2466   u32 first_sw_if_index;
2467   int i;
2468
2469   count = ntohl (mp->count);
2470   first_sw_if_index = ntohl (mp->first_sw_if_index);
2471
2472   v_packets = (u64 *) & mp->data;
2473   for (i = 0; i < count; i++)
2474     {
2475       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2476       set_simple_interface_counter (mp->vnet_counter_type,
2477                                     first_sw_if_index + i, packets);
2478       v_packets++;
2479     }
2480 }
2481
2482 static void vl_api_vnet_interface_combined_counters_t_handler_json
2483   (vl_api_vnet_interface_combined_counters_t * mp)
2484 {
2485   interface_counter_t counter;
2486   vlib_counter_t *v;
2487   u32 first_sw_if_index;
2488   int i;
2489   u32 count;
2490
2491   count = ntohl (mp->count);
2492   first_sw_if_index = ntohl (mp->first_sw_if_index);
2493
2494   v = (vlib_counter_t *) & mp->data;
2495   for (i = 0; i < count; i++)
2496     {
2497       counter.packets =
2498         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2499       counter.bytes =
2500         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2501       set_combined_interface_counter (mp->vnet_counter_type,
2502                                       first_sw_if_index + i, counter);
2503       v++;
2504     }
2505 }
2506
2507 static u32
2508 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2509 {
2510   vat_main_t *vam = &vat_main;
2511   u32 i;
2512
2513   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2514     {
2515       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2516         {
2517           return i;
2518         }
2519     }
2520   return ~0;
2521 }
2522
2523 static u32
2524 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   u32 i;
2528
2529   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2530     {
2531       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2532         {
2533           return i;
2534         }
2535     }
2536   return ~0;
2537 }
2538
2539 static void vl_api_vnet_ip4_fib_counters_t_handler
2540   (vl_api_vnet_ip4_fib_counters_t * mp)
2541 {
2542   /* not supported */
2543 }
2544
2545 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2546   (vl_api_vnet_ip4_fib_counters_t * mp)
2547 {
2548   vat_main_t *vam = &vat_main;
2549   vl_api_ip4_fib_counter_t *v;
2550   ip4_fib_counter_t *counter;
2551   struct in_addr ip4;
2552   u32 vrf_id;
2553   u32 vrf_index;
2554   u32 count;
2555   int i;
2556
2557   vrf_id = ntohl (mp->vrf_id);
2558   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2559   if (~0 == vrf_index)
2560     {
2561       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2562       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2563       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2564       vec_validate (vam->ip4_fib_counters, vrf_index);
2565       vam->ip4_fib_counters[vrf_index] = NULL;
2566     }
2567
2568   vec_free (vam->ip4_fib_counters[vrf_index]);
2569   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2570   count = ntohl (mp->count);
2571   for (i = 0; i < count; i++)
2572     {
2573       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2574       counter = &vam->ip4_fib_counters[vrf_index][i];
2575       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2576       counter->address = ip4;
2577       counter->address_length = v->address_length;
2578       counter->packets = clib_net_to_host_u64 (v->packets);
2579       counter->bytes = clib_net_to_host_u64 (v->bytes);
2580       v++;
2581     }
2582 }
2583
2584 static void vl_api_vnet_ip4_nbr_counters_t_handler
2585   (vl_api_vnet_ip4_nbr_counters_t * mp)
2586 {
2587   /* not supported */
2588 }
2589
2590 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2591   (vl_api_vnet_ip4_nbr_counters_t * mp)
2592 {
2593   vat_main_t *vam = &vat_main;
2594   vl_api_ip4_nbr_counter_t *v;
2595   ip4_nbr_counter_t *counter;
2596   u32 sw_if_index;
2597   u32 count;
2598   int i;
2599
2600   sw_if_index = ntohl (mp->sw_if_index);
2601   count = ntohl (mp->count);
2602   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2603
2604   if (mp->begin)
2605     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2606
2607   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2608   for (i = 0; i < count; i++)
2609     {
2610       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2611       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2612       counter->address.s_addr = v->address;
2613       counter->packets = clib_net_to_host_u64 (v->packets);
2614       counter->bytes = clib_net_to_host_u64 (v->bytes);
2615       counter->linkt = v->link_type;
2616       v++;
2617     }
2618 }
2619
2620 static void vl_api_vnet_ip6_fib_counters_t_handler
2621   (vl_api_vnet_ip6_fib_counters_t * mp)
2622 {
2623   /* not supported */
2624 }
2625
2626 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2627   (vl_api_vnet_ip6_fib_counters_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vl_api_ip6_fib_counter_t *v;
2631   ip6_fib_counter_t *counter;
2632   struct in6_addr ip6;
2633   u32 vrf_id;
2634   u32 vrf_index;
2635   u32 count;
2636   int i;
2637
2638   vrf_id = ntohl (mp->vrf_id);
2639   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2640   if (~0 == vrf_index)
2641     {
2642       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2643       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2644       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2645       vec_validate (vam->ip6_fib_counters, vrf_index);
2646       vam->ip6_fib_counters[vrf_index] = NULL;
2647     }
2648
2649   vec_free (vam->ip6_fib_counters[vrf_index]);
2650   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2651   count = ntohl (mp->count);
2652   for (i = 0; i < count; i++)
2653     {
2654       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2655       counter = &vam->ip6_fib_counters[vrf_index][i];
2656       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2657       counter->address = ip6;
2658       counter->address_length = v->address_length;
2659       counter->packets = clib_net_to_host_u64 (v->packets);
2660       counter->bytes = clib_net_to_host_u64 (v->bytes);
2661       v++;
2662     }
2663 }
2664
2665 static void vl_api_vnet_ip6_nbr_counters_t_handler
2666   (vl_api_vnet_ip6_nbr_counters_t * mp)
2667 {
2668   /* not supported */
2669 }
2670
2671 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2672   (vl_api_vnet_ip6_nbr_counters_t * mp)
2673 {
2674   vat_main_t *vam = &vat_main;
2675   vl_api_ip6_nbr_counter_t *v;
2676   ip6_nbr_counter_t *counter;
2677   struct in6_addr ip6;
2678   u32 sw_if_index;
2679   u32 count;
2680   int i;
2681
2682   sw_if_index = ntohl (mp->sw_if_index);
2683   count = ntohl (mp->count);
2684   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2685
2686   if (mp->begin)
2687     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2688
2689   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2690   for (i = 0; i < count; i++)
2691     {
2692       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2693       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2694       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2695       counter->address = ip6;
2696       counter->packets = clib_net_to_host_u64 (v->packets);
2697       counter->bytes = clib_net_to_host_u64 (v->bytes);
2698       v++;
2699     }
2700 }
2701
2702 static void vl_api_get_first_msg_id_reply_t_handler
2703   (vl_api_get_first_msg_id_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (vam->async_mode)
2709     {
2710       vam->async_errors += (retval < 0);
2711     }
2712   else
2713     {
2714       vam->retval = retval;
2715       vam->result_ready = 1;
2716     }
2717   if (retval >= 0)
2718     {
2719       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2720     }
2721 }
2722
2723 static void vl_api_get_first_msg_id_reply_t_handler_json
2724   (vl_api_get_first_msg_id_reply_t * mp)
2725 {
2726   vat_main_t *vam = &vat_main;
2727   vat_json_node_t node;
2728
2729   vat_json_init_object (&node);
2730   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2731   vat_json_object_add_uint (&node, "first_msg_id",
2732                             (uint) ntohs (mp->first_msg_id));
2733
2734   vat_json_print (vam->ofp, &node);
2735   vat_json_free (&node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static void vl_api_get_node_graph_reply_t_handler
2742   (vl_api_get_node_graph_reply_t * mp)
2743 {
2744   vat_main_t *vam = &vat_main;
2745   api_main_t *am = &api_main;
2746   i32 retval = ntohl (mp->retval);
2747   u8 *pvt_copy, *reply;
2748   void *oldheap;
2749   vlib_node_t *node;
2750   int i;
2751
2752   if (vam->async_mode)
2753     {
2754       vam->async_errors += (retval < 0);
2755     }
2756   else
2757     {
2758       vam->retval = retval;
2759       vam->result_ready = 1;
2760     }
2761
2762   /* "Should never happen..." */
2763   if (retval != 0)
2764     return;
2765
2766   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2767   pvt_copy = vec_dup (reply);
2768
2769   /* Toss the shared-memory original... */
2770   pthread_mutex_lock (&am->vlib_rp->mutex);
2771   oldheap = svm_push_data_heap (am->vlib_rp);
2772
2773   vec_free (reply);
2774
2775   svm_pop_heap (oldheap);
2776   pthread_mutex_unlock (&am->vlib_rp->mutex);
2777
2778   if (vam->graph_nodes)
2779     {
2780       hash_free (vam->graph_node_index_by_name);
2781
2782       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2783         {
2784           node = vam->graph_nodes[i];
2785           vec_free (node->name);
2786           vec_free (node->next_nodes);
2787           vec_free (node);
2788         }
2789       vec_free (vam->graph_nodes);
2790     }
2791
2792   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2793   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2794   vec_free (pvt_copy);
2795
2796   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2797     {
2798       node = vam->graph_nodes[i];
2799       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2800     }
2801 }
2802
2803 static void vl_api_get_node_graph_reply_t_handler_json
2804   (vl_api_get_node_graph_reply_t * mp)
2805 {
2806   vat_main_t *vam = &vat_main;
2807   api_main_t *am = &api_main;
2808   void *oldheap;
2809   vat_json_node_t node;
2810   u8 *reply;
2811
2812   /* $$$$ make this real? */
2813   vat_json_init_object (&node);
2814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2815   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2816
2817   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2818
2819   /* Toss the shared-memory original... */
2820   pthread_mutex_lock (&am->vlib_rp->mutex);
2821   oldheap = svm_push_data_heap (am->vlib_rp);
2822
2823   vec_free (reply);
2824
2825   svm_pop_heap (oldheap);
2826   pthread_mutex_unlock (&am->vlib_rp->mutex);
2827
2828   vat_json_print (vam->ofp, &node);
2829   vat_json_free (&node);
2830
2831   vam->retval = ntohl (mp->retval);
2832   vam->result_ready = 1;
2833 }
2834
2835 static void
2836 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   u8 *s = 0;
2840
2841   if (mp->local)
2842     {
2843       s = format (s, "%=16d%=16d%=16d",
2844                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2845     }
2846   else
2847     {
2848       s = format (s, "%=16U%=16d%=16d",
2849                   mp->is_ipv6 ? format_ip6_address :
2850                   format_ip4_address,
2851                   mp->ip_address, mp->priority, mp->weight);
2852     }
2853
2854   print (vam->ofp, "%v", s);
2855   vec_free (s);
2856 }
2857
2858 static void
2859 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2860 {
2861   vat_main_t *vam = &vat_main;
2862   vat_json_node_t *node = NULL;
2863   struct in6_addr ip6;
2864   struct in_addr ip4;
2865
2866   if (VAT_JSON_ARRAY != vam->json_tree.type)
2867     {
2868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2869       vat_json_init_array (&vam->json_tree);
2870     }
2871   node = vat_json_array_add (&vam->json_tree);
2872   vat_json_init_object (node);
2873
2874   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2875   vat_json_object_add_uint (node, "priority", mp->priority);
2876   vat_json_object_add_uint (node, "weight", mp->weight);
2877
2878   if (mp->local)
2879     vat_json_object_add_uint (node, "sw_if_index",
2880                               clib_net_to_host_u32 (mp->sw_if_index));
2881   else
2882     {
2883       if (mp->is_ipv6)
2884         {
2885           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2886           vat_json_object_add_ip6 (node, "address", ip6);
2887         }
2888       else
2889         {
2890           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2891           vat_json_object_add_ip4 (node, "address", ip4);
2892         }
2893     }
2894 }
2895
2896 static void
2897 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2898                                           mp)
2899 {
2900   vat_main_t *vam = &vat_main;
2901   u8 *ls_name = 0;
2902
2903   ls_name = format (0, "%s", mp->ls_name);
2904
2905   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2906          ls_name);
2907   vec_free (ls_name);
2908 }
2909
2910 static void
2911   vl_api_one_locator_set_details_t_handler_json
2912   (vl_api_one_locator_set_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node = 0;
2916   u8 *ls_name = 0;
2917
2918   ls_name = format (0, "%s", mp->ls_name);
2919   vec_add1 (ls_name, 0);
2920
2921   if (VAT_JSON_ARRAY != vam->json_tree.type)
2922     {
2923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2924       vat_json_init_array (&vam->json_tree);
2925     }
2926   node = vat_json_array_add (&vam->json_tree);
2927
2928   vat_json_init_object (node);
2929   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2930   vat_json_object_add_uint (node, "ls_index",
2931                             clib_net_to_host_u32 (mp->ls_index));
2932   vec_free (ls_name);
2933 }
2934
2935 typedef struct
2936 {
2937   u32 spi;
2938   u8 si;
2939 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2940
2941 uword
2942 unformat_nsh_address (unformat_input_t * input, va_list * args)
2943 {
2944   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2945   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2946 }
2947
2948 u8 *
2949 format_nsh_address_vat (u8 * s, va_list * args)
2950 {
2951   nsh_t *a = va_arg (*args, nsh_t *);
2952   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2953 }
2954
2955 static u8 *
2956 format_lisp_flat_eid (u8 * s, va_list * args)
2957 {
2958   u32 type = va_arg (*args, u32);
2959   u8 *eid = va_arg (*args, u8 *);
2960   u32 eid_len = va_arg (*args, u32);
2961
2962   switch (type)
2963     {
2964     case 0:
2965       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2966     case 1:
2967       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2968     case 2:
2969       return format (s, "%U", format_ethernet_address, eid);
2970     case 3:
2971       return format (s, "%U", format_nsh_address_vat, eid);
2972     }
2973   return 0;
2974 }
2975
2976 static u8 *
2977 format_lisp_eid_vat (u8 * s, va_list * args)
2978 {
2979   u32 type = va_arg (*args, u32);
2980   u8 *eid = va_arg (*args, u8 *);
2981   u32 eid_len = va_arg (*args, u32);
2982   u8 *seid = va_arg (*args, u8 *);
2983   u32 seid_len = va_arg (*args, u32);
2984   u32 is_src_dst = va_arg (*args, u32);
2985
2986   if (is_src_dst)
2987     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2988
2989   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2990
2991   return s;
2992 }
2993
2994 static void
2995 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2996 {
2997   vat_main_t *vam = &vat_main;
2998   u8 *s = 0, *eid = 0;
2999
3000   if (~0 == mp->locator_set_index)
3001     s = format (0, "action: %d", mp->action);
3002   else
3003     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3004
3005   eid = format (0, "%U", format_lisp_eid_vat,
3006                 mp->eid_type,
3007                 mp->eid,
3008                 mp->eid_prefix_len,
3009                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3010   vec_add1 (eid, 0);
3011
3012   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3013          clib_net_to_host_u32 (mp->vni),
3014          eid,
3015          mp->is_local ? "local" : "remote",
3016          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3017          clib_net_to_host_u16 (mp->key_id), mp->key);
3018
3019   vec_free (s);
3020   vec_free (eid);
3021 }
3022
3023 static void
3024 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3025                                              * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   vat_json_node_t *node = 0;
3029   u8 *eid = 0;
3030
3031   if (VAT_JSON_ARRAY != vam->json_tree.type)
3032     {
3033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3034       vat_json_init_array (&vam->json_tree);
3035     }
3036   node = vat_json_array_add (&vam->json_tree);
3037
3038   vat_json_init_object (node);
3039   if (~0 == mp->locator_set_index)
3040     vat_json_object_add_uint (node, "action", mp->action);
3041   else
3042     vat_json_object_add_uint (node, "locator_set_index",
3043                               clib_net_to_host_u32 (mp->locator_set_index));
3044
3045   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3046   if (mp->eid_type == 3)
3047     {
3048       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3049       vat_json_init_object (nsh_json);
3050       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3051       vat_json_object_add_uint (nsh_json, "spi",
3052                                 clib_net_to_host_u32 (nsh->spi));
3053       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3054     }
3055   else
3056     {
3057       eid = format (0, "%U", format_lisp_eid_vat,
3058                     mp->eid_type,
3059                     mp->eid,
3060                     mp->eid_prefix_len,
3061                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3062       vec_add1 (eid, 0);
3063       vat_json_object_add_string_copy (node, "eid", eid);
3064       vec_free (eid);
3065     }
3066   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3067   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3068   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3069
3070   if (mp->key_id)
3071     {
3072       vat_json_object_add_uint (node, "key_id",
3073                                 clib_net_to_host_u16 (mp->key_id));
3074       vat_json_object_add_string_copy (node, "key", mp->key);
3075     }
3076 }
3077
3078 static void
3079 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3080 {
3081   vat_main_t *vam = &vat_main;
3082   u8 *seid = 0, *deid = 0;
3083   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3084
3085   deid = format (0, "%U", format_lisp_eid_vat,
3086                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3087
3088   seid = format (0, "%U", format_lisp_eid_vat,
3089                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3090
3091   vec_add1 (deid, 0);
3092   vec_add1 (seid, 0);
3093
3094   if (mp->is_ip4)
3095     format_ip_address_fcn = format_ip4_address;
3096   else
3097     format_ip_address_fcn = format_ip6_address;
3098
3099
3100   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3101          clib_net_to_host_u32 (mp->vni),
3102          seid, deid,
3103          format_ip_address_fcn, mp->lloc,
3104          format_ip_address_fcn, mp->rloc,
3105          clib_net_to_host_u32 (mp->pkt_count),
3106          clib_net_to_host_u32 (mp->bytes));
3107
3108   vec_free (deid);
3109   vec_free (seid);
3110 }
3111
3112 static void
3113 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3114 {
3115   struct in6_addr ip6;
3116   struct in_addr ip4;
3117   vat_main_t *vam = &vat_main;
3118   vat_json_node_t *node = 0;
3119   u8 *deid = 0, *seid = 0;
3120
3121   if (VAT_JSON_ARRAY != vam->json_tree.type)
3122     {
3123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3124       vat_json_init_array (&vam->json_tree);
3125     }
3126   node = vat_json_array_add (&vam->json_tree);
3127
3128   vat_json_init_object (node);
3129   deid = format (0, "%U", format_lisp_eid_vat,
3130                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3131
3132   seid = format (0, "%U", format_lisp_eid_vat,
3133                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3134
3135   vec_add1 (deid, 0);
3136   vec_add1 (seid, 0);
3137
3138   vat_json_object_add_string_copy (node, "seid", seid);
3139   vat_json_object_add_string_copy (node, "deid", deid);
3140   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3141
3142   if (mp->is_ip4)
3143     {
3144       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3145       vat_json_object_add_ip4 (node, "lloc", ip4);
3146       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3147       vat_json_object_add_ip4 (node, "rloc", ip4);
3148     }
3149   else
3150     {
3151       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3152       vat_json_object_add_ip6 (node, "lloc", ip6);
3153       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3154       vat_json_object_add_ip6 (node, "rloc", ip6);
3155     }
3156   vat_json_object_add_uint (node, "pkt_count",
3157                             clib_net_to_host_u32 (mp->pkt_count));
3158   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3159
3160   vec_free (deid);
3161   vec_free (seid);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_map_details_t_handler
3166   (vl_api_one_eid_table_map_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   u8 *line = format (0, "%=10d%=10d",
3171                      clib_net_to_host_u32 (mp->vni),
3172                      clib_net_to_host_u32 (mp->dp_table));
3173   print (vam->ofp, "%v", line);
3174   vec_free (line);
3175 }
3176
3177 static void
3178   vl_api_one_eid_table_map_details_t_handler_json
3179   (vl_api_one_eid_table_map_details_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182   vat_json_node_t *node = NULL;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191   vat_json_object_add_uint (node, "dp_table",
3192                             clib_net_to_host_u32 (mp->dp_table));
3193   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3194 }
3195
3196 static void
3197   vl_api_one_eid_table_vni_details_t_handler
3198   (vl_api_one_eid_table_vni_details_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201
3202   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_vni_details_t_handler_json
3209   (vl_api_one_eid_table_vni_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, "vni", clib_net_to_host_u32 (mp->vni));
3222 }
3223
3224 static void
3225   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3226   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3232   print (vam->ofp, "fallback threshold value: %d", mp->value);
3233
3234   vam->retval = retval;
3235   vam->result_ready = 1;
3236 }
3237
3238 static void
3239   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3240   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t _node, *node = &_node;
3244   int retval = clib_net_to_host_u32 (mp->retval);
3245
3246   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3247   vat_json_init_object (node);
3248   vat_json_object_add_uint (node, "value", mp->value);
3249
3250   vat_json_print (vam->ofp, node);
3251   vat_json_free (node);
3252
3253   vam->retval = retval;
3254   vam->result_ready = 1;
3255 }
3256
3257 static void
3258   vl_api_show_one_map_register_state_reply_t_handler
3259   (vl_api_show_one_map_register_state_reply_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   int retval = clib_net_to_host_u32 (mp->retval);
3263
3264   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3265
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_show_one_map_register_state_reply_t_handler_json
3272   (vl_api_show_one_map_register_state_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t _node, *node = &_node;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3279
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292   vl_api_show_one_rloc_probe_state_reply_t_handler
3293   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   int retval = clib_net_to_host_u32 (mp->retval);
3297
3298   if (retval)
3299     goto end;
3300
3301   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3302 end:
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3309   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t _node, *node = &_node;
3313   int retval = clib_net_to_host_u32 (mp->retval);
3314
3315   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3316   vat_json_init_object (node);
3317   vat_json_object_add_string_copy (node, "state", s);
3318
3319   vat_json_print (vam->ofp, node);
3320   vat_json_free (node);
3321
3322   vam->retval = retval;
3323   vam->result_ready = 1;
3324   vec_free (s);
3325 }
3326
3327 static void
3328   vl_api_show_one_stats_enable_disable_reply_t_handler
3329   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   int retval = clib_net_to_host_u32 (mp->retval);
3333
3334   if (retval)
3335     goto end;
3336
3337   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3338 end:
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341 }
3342
3343 static void
3344   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3345   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3346 {
3347   vat_main_t *vam = &vat_main;
3348   vat_json_node_t _node, *node = &_node;
3349   int retval = clib_net_to_host_u32 (mp->retval);
3350
3351   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3352   vat_json_init_object (node);
3353   vat_json_object_add_string_copy (node, "state", s);
3354
3355   vat_json_print (vam->ofp, node);
3356   vat_json_free (node);
3357
3358   vam->retval = retval;
3359   vam->result_ready = 1;
3360   vec_free (s);
3361 }
3362
3363 static void
3364 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3365 {
3366   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3367   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3368   e->vni = clib_net_to_host_u32 (e->vni);
3369 }
3370
3371 static void
3372   gpe_fwd_entries_get_reply_t_net_to_host
3373   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3374 {
3375   u32 i;
3376
3377   mp->count = clib_net_to_host_u32 (mp->count);
3378   for (i = 0; i < mp->count; i++)
3379     {
3380       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3381     }
3382 }
3383
3384 static u8 *
3385 format_gpe_encap_mode (u8 * s, va_list * args)
3386 {
3387   u32 mode = va_arg (*args, u32);
3388
3389   switch (mode)
3390     {
3391     case 0:
3392       return format (s, "lisp");
3393     case 1:
3394       return format (s, "vxlan");
3395     }
3396   return 0;
3397 }
3398
3399 static void
3400   vl_api_gpe_get_encap_mode_reply_t_handler
3401   (vl_api_gpe_get_encap_mode_reply_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3406   vam->retval = ntohl (mp->retval);
3407   vam->result_ready = 1;
3408 }
3409
3410 static void
3411   vl_api_gpe_get_encap_mode_reply_t_handler_json
3412   (vl_api_gpe_get_encap_mode_reply_t * mp)
3413 {
3414   vat_main_t *vam = &vat_main;
3415   vat_json_node_t node;
3416
3417   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3418   vec_add1 (encap_mode, 0);
3419
3420   vat_json_init_object (&node);
3421   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3422
3423   vec_free (encap_mode);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vam->retval = ntohl (mp->retval);
3428   vam->result_ready = 1;
3429 }
3430
3431 static void
3432   vl_api_gpe_fwd_entry_path_details_t_handler
3433   (vl_api_gpe_fwd_entry_path_details_t * mp)
3434 {
3435   vat_main_t *vam = &vat_main;
3436   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3437
3438   if (mp->lcl_loc.is_ip4)
3439     format_ip_address_fcn = format_ip4_address;
3440   else
3441     format_ip_address_fcn = format_ip6_address;
3442
3443   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3444          format_ip_address_fcn, &mp->lcl_loc,
3445          format_ip_address_fcn, &mp->rmt_loc);
3446 }
3447
3448 static void
3449 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3450 {
3451   struct in6_addr ip6;
3452   struct in_addr ip4;
3453
3454   if (loc->is_ip4)
3455     {
3456       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3457       vat_json_object_add_ip4 (n, "address", ip4);
3458     }
3459   else
3460     {
3461       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3462       vat_json_object_add_ip6 (n, "address", ip6);
3463     }
3464   vat_json_object_add_uint (n, "weight", loc->weight);
3465 }
3466
3467 static void
3468   vl_api_gpe_fwd_entry_path_details_t_handler_json
3469   (vl_api_gpe_fwd_entry_path_details_t * mp)
3470 {
3471   vat_main_t *vam = &vat_main;
3472   vat_json_node_t *node = NULL;
3473   vat_json_node_t *loc_node;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481   vat_json_init_object (node);
3482
3483   loc_node = vat_json_object_add (node, "local_locator");
3484   vat_json_init_object (loc_node);
3485   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3486
3487   loc_node = vat_json_object_add (node, "remote_locator");
3488   vat_json_init_object (loc_node);
3489   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3490 }
3491
3492 static void
3493   vl_api_gpe_fwd_entries_get_reply_t_handler
3494   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3495 {
3496   vat_main_t *vam = &vat_main;
3497   u32 i;
3498   int retval = clib_net_to_host_u32 (mp->retval);
3499   vl_api_gpe_fwd_entry_t *e;
3500
3501   if (retval)
3502     goto end;
3503
3504   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3505
3506   for (i = 0; i < mp->count; i++)
3507     {
3508       e = &mp->entries[i];
3509       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3510              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3511              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3512     }
3513
3514 end:
3515   vam->retval = retval;
3516   vam->result_ready = 1;
3517 }
3518
3519 static void
3520   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3521   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3522 {
3523   u8 *s = 0;
3524   vat_main_t *vam = &vat_main;
3525   vat_json_node_t *e = 0, root;
3526   u32 i;
3527   int retval = clib_net_to_host_u32 (mp->retval);
3528   vl_api_gpe_fwd_entry_t *fwd;
3529
3530   if (retval)
3531     goto end;
3532
3533   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3534   vat_json_init_array (&root);
3535
3536   for (i = 0; i < mp->count; i++)
3537     {
3538       e = vat_json_array_add (&root);
3539       fwd = &mp->entries[i];
3540
3541       vat_json_init_object (e);
3542       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3543       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3544       vat_json_object_add_int (e, "vni", fwd->vni);
3545       vat_json_object_add_int (e, "action", fwd->action);
3546
3547       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3548                   fwd->leid_prefix_len);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "leid", s);
3551       vec_free (s);
3552
3553       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3554                   fwd->reid_prefix_len);
3555       vec_add1 (s, 0);
3556       vat_json_object_add_string_copy (e, "reid", s);
3557       vec_free (s);
3558     }
3559
3560   vat_json_print (vam->ofp, &root);
3561   vat_json_free (&root);
3562
3563 end:
3564   vam->retval = retval;
3565   vam->result_ready = 1;
3566 }
3567
3568 static void
3569   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3570   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3571 {
3572   vat_main_t *vam = &vat_main;
3573   u32 i, n;
3574   int retval = clib_net_to_host_u32 (mp->retval);
3575   vl_api_gpe_native_fwd_rpath_t *r;
3576
3577   if (retval)
3578     goto end;
3579
3580   n = clib_net_to_host_u32 (mp->count);
3581
3582   for (i = 0; i < n; i++)
3583     {
3584       r = &mp->entries[i];
3585       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3586              clib_net_to_host_u32 (r->fib_index),
3587              clib_net_to_host_u32 (r->nh_sw_if_index),
3588              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3589     }
3590
3591 end:
3592   vam->retval = retval;
3593   vam->result_ready = 1;
3594 }
3595
3596 static void
3597   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3598   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3599 {
3600   vat_main_t *vam = &vat_main;
3601   vat_json_node_t root, *e;
3602   u32 i, n;
3603   int retval = clib_net_to_host_u32 (mp->retval);
3604   vl_api_gpe_native_fwd_rpath_t *r;
3605   u8 *s;
3606
3607   if (retval)
3608     goto end;
3609
3610   n = clib_net_to_host_u32 (mp->count);
3611   vat_json_init_array (&root);
3612
3613   for (i = 0; i < n; i++)
3614     {
3615       e = vat_json_array_add (&root);
3616       vat_json_init_object (e);
3617       r = &mp->entries[i];
3618       s =
3619         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3620                 r->nh_addr);
3621       vec_add1 (s, 0);
3622       vat_json_object_add_string_copy (e, "ip4", s);
3623       vec_free (s);
3624
3625       vat_json_object_add_uint (e, "fib_index",
3626                                 clib_net_to_host_u32 (r->fib_index));
3627       vat_json_object_add_uint (e, "nh_sw_if_index",
3628                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3629     }
3630
3631   vat_json_print (vam->ofp, &root);
3632   vat_json_free (&root);
3633
3634 end:
3635   vam->retval = retval;
3636   vam->result_ready = 1;
3637 }
3638
3639 static void
3640   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3641   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3642 {
3643   vat_main_t *vam = &vat_main;
3644   u32 i, n;
3645   int retval = clib_net_to_host_u32 (mp->retval);
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651
3652   for (i = 0; i < n; i++)
3653     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3654
3655 end:
3656   vam->retval = retval;
3657   vam->result_ready = 1;
3658 }
3659
3660 static void
3661   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3662   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3663 {
3664   vat_main_t *vam = &vat_main;
3665   vat_json_node_t root;
3666   u32 i, n;
3667   int retval = clib_net_to_host_u32 (mp->retval);
3668
3669   if (retval)
3670     goto end;
3671
3672   n = clib_net_to_host_u32 (mp->count);
3673   vat_json_init_array (&root);
3674
3675   for (i = 0; i < n; i++)
3676     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3677
3678   vat_json_print (vam->ofp, &root);
3679   vat_json_free (&root);
3680
3681 end:
3682   vam->retval = retval;
3683   vam->result_ready = 1;
3684 }
3685
3686 static void
3687   vl_api_one_ndp_entries_get_reply_t_handler
3688   (vl_api_one_ndp_entries_get_reply_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   u32 i, n;
3692   int retval = clib_net_to_host_u32 (mp->retval);
3693
3694   if (retval)
3695     goto end;
3696
3697   n = clib_net_to_host_u32 (mp->count);
3698
3699   for (i = 0; i < n; i++)
3700     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3701            format_ethernet_address, mp->entries[i].mac);
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_ndp_entries_get_reply_t_handler_json
3710   (vl_api_one_ndp_entries_get_reply_t * mp)
3711 {
3712   u8 *s = 0;
3713   vat_main_t *vam = &vat_main;
3714   vat_json_node_t *e = 0, root;
3715   u32 i, n;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717   vl_api_one_ndp_entry_t *arp_entry;
3718
3719   if (retval)
3720     goto end;
3721
3722   n = clib_net_to_host_u32 (mp->count);
3723   vat_json_init_array (&root);
3724
3725   for (i = 0; i < n; i++)
3726     {
3727       e = vat_json_array_add (&root);
3728       arp_entry = &mp->entries[i];
3729
3730       vat_json_init_object (e);
3731       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3732       vec_add1 (s, 0);
3733
3734       vat_json_object_add_string_copy (e, "mac", s);
3735       vec_free (s);
3736
3737       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3738       vec_add1 (s, 0);
3739       vat_json_object_add_string_copy (e, "ip6", s);
3740       vec_free (s);
3741     }
3742
3743   vat_json_print (vam->ofp, &root);
3744   vat_json_free (&root);
3745
3746 end:
3747   vam->retval = retval;
3748   vam->result_ready = 1;
3749 }
3750
3751 static void
3752   vl_api_one_l2_arp_entries_get_reply_t_handler
3753   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3754 {
3755   vat_main_t *vam = &vat_main;
3756   u32 i, n;
3757   int retval = clib_net_to_host_u32 (mp->retval);
3758
3759   if (retval)
3760     goto end;
3761
3762   n = clib_net_to_host_u32 (mp->count);
3763
3764   for (i = 0; i < n; i++)
3765     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3766            format_ethernet_address, mp->entries[i].mac);
3767
3768 end:
3769   vam->retval = retval;
3770   vam->result_ready = 1;
3771 }
3772
3773 static void
3774   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3775   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3776 {
3777   u8 *s = 0;
3778   vat_main_t *vam = &vat_main;
3779   vat_json_node_t *e = 0, root;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782   vl_api_one_l2_arp_entry_t *arp_entry;
3783
3784   if (retval)
3785     goto end;
3786
3787   n = clib_net_to_host_u32 (mp->count);
3788   vat_json_init_array (&root);
3789
3790   for (i = 0; i < n; i++)
3791     {
3792       e = vat_json_array_add (&root);
3793       arp_entry = &mp->entries[i];
3794
3795       vat_json_init_object (e);
3796       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3797       vec_add1 (s, 0);
3798
3799       vat_json_object_add_string_copy (e, "mac", s);
3800       vec_free (s);
3801
3802       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3803       vec_add1 (s, 0);
3804       vat_json_object_add_string_copy (e, "ip4", s);
3805       vec_free (s);
3806     }
3807
3808   vat_json_print (vam->ofp, &root);
3809   vat_json_free (&root);
3810
3811 end:
3812   vam->retval = retval;
3813   vam->result_ready = 1;
3814 }
3815
3816 static void
3817 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3818 {
3819   vat_main_t *vam = &vat_main;
3820   u32 i, n;
3821   int retval = clib_net_to_host_u32 (mp->retval);
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827
3828   for (i = 0; i < n; i++)
3829     {
3830       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3831     }
3832
3833 end:
3834   vam->retval = retval;
3835   vam->result_ready = 1;
3836 }
3837
3838 static void
3839   vl_api_one_ndp_bd_get_reply_t_handler_json
3840   (vl_api_one_ndp_bd_get_reply_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843   vat_json_node_t root;
3844   u32 i, n;
3845   int retval = clib_net_to_host_u32 (mp->retval);
3846
3847   if (retval)
3848     goto end;
3849
3850   n = clib_net_to_host_u32 (mp->count);
3851   vat_json_init_array (&root);
3852
3853   for (i = 0; i < n; i++)
3854     {
3855       vat_json_array_add_uint (&root,
3856                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3857     }
3858
3859   vat_json_print (vam->ofp, &root);
3860   vat_json_free (&root);
3861
3862 end:
3863   vam->retval = retval;
3864   vam->result_ready = 1;
3865 }
3866
3867 static void
3868   vl_api_one_l2_arp_bd_get_reply_t_handler
3869   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3870 {
3871   vat_main_t *vam = &vat_main;
3872   u32 i, n;
3873   int retval = clib_net_to_host_u32 (mp->retval);
3874
3875   if (retval)
3876     goto end;
3877
3878   n = clib_net_to_host_u32 (mp->count);
3879
3880   for (i = 0; i < n; i++)
3881     {
3882       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3883     }
3884
3885 end:
3886   vam->retval = retval;
3887   vam->result_ready = 1;
3888 }
3889
3890 static void
3891   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3892   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3893 {
3894   vat_main_t *vam = &vat_main;
3895   vat_json_node_t root;
3896   u32 i, n;
3897   int retval = clib_net_to_host_u32 (mp->retval);
3898
3899   if (retval)
3900     goto end;
3901
3902   n = clib_net_to_host_u32 (mp->count);
3903   vat_json_init_array (&root);
3904
3905   for (i = 0; i < n; i++)
3906     {
3907       vat_json_array_add_uint (&root,
3908                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3909     }
3910
3911   vat_json_print (vam->ofp, &root);
3912   vat_json_free (&root);
3913
3914 end:
3915   vam->retval = retval;
3916   vam->result_ready = 1;
3917 }
3918
3919 static void
3920   vl_api_one_adjacencies_get_reply_t_handler
3921   (vl_api_one_adjacencies_get_reply_t * mp)
3922 {
3923   vat_main_t *vam = &vat_main;
3924   u32 i, n;
3925   int retval = clib_net_to_host_u32 (mp->retval);
3926   vl_api_one_adjacency_t *a;
3927
3928   if (retval)
3929     goto end;
3930
3931   n = clib_net_to_host_u32 (mp->count);
3932
3933   for (i = 0; i < n; i++)
3934     {
3935       a = &mp->adjacencies[i];
3936       print (vam->ofp, "%U %40U",
3937              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3938              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3939     }
3940
3941 end:
3942   vam->retval = retval;
3943   vam->result_ready = 1;
3944 }
3945
3946 static void
3947   vl_api_one_adjacencies_get_reply_t_handler_json
3948   (vl_api_one_adjacencies_get_reply_t * mp)
3949 {
3950   u8 *s = 0;
3951   vat_main_t *vam = &vat_main;
3952   vat_json_node_t *e = 0, root;
3953   u32 i, n;
3954   int retval = clib_net_to_host_u32 (mp->retval);
3955   vl_api_one_adjacency_t *a;
3956
3957   if (retval)
3958     goto end;
3959
3960   n = clib_net_to_host_u32 (mp->count);
3961   vat_json_init_array (&root);
3962
3963   for (i = 0; i < n; i++)
3964     {
3965       e = vat_json_array_add (&root);
3966       a = &mp->adjacencies[i];
3967
3968       vat_json_init_object (e);
3969       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3970                   a->leid_prefix_len);
3971       vec_add1 (s, 0);
3972       vat_json_object_add_string_copy (e, "leid", s);
3973       vec_free (s);
3974
3975       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3976                   a->reid_prefix_len);
3977       vec_add1 (s, 0);
3978       vat_json_object_add_string_copy (e, "reid", s);
3979       vec_free (s);
3980     }
3981
3982   vat_json_print (vam->ofp, &root);
3983   vat_json_free (&root);
3984
3985 end:
3986   vam->retval = retval;
3987   vam->result_ready = 1;
3988 }
3989
3990 static void
3991 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994
3995   print (vam->ofp, "%=20U",
3996          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3997          mp->ip_address);
3998 }
3999
4000 static void
4001   vl_api_one_map_server_details_t_handler_json
4002   (vl_api_one_map_server_details_t * mp)
4003 {
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t *node = NULL;
4006   struct in6_addr ip6;
4007   struct in_addr ip4;
4008
4009   if (VAT_JSON_ARRAY != vam->json_tree.type)
4010     {
4011       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4012       vat_json_init_array (&vam->json_tree);
4013     }
4014   node = vat_json_array_add (&vam->json_tree);
4015
4016   vat_json_init_object (node);
4017   if (mp->is_ipv6)
4018     {
4019       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4020       vat_json_object_add_ip6 (node, "map-server", ip6);
4021     }
4022   else
4023     {
4024       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4025       vat_json_object_add_ip4 (node, "map-server", ip4);
4026     }
4027 }
4028
4029 static void
4030 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4031                                            * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034
4035   print (vam->ofp, "%=20U",
4036          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4037          mp->ip_address);
4038 }
4039
4040 static void
4041   vl_api_one_map_resolver_details_t_handler_json
4042   (vl_api_one_map_resolver_details_t * mp)
4043 {
4044   vat_main_t *vam = &vat_main;
4045   vat_json_node_t *node = NULL;
4046   struct in6_addr ip6;
4047   struct in_addr ip4;
4048
4049   if (VAT_JSON_ARRAY != vam->json_tree.type)
4050     {
4051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4052       vat_json_init_array (&vam->json_tree);
4053     }
4054   node = vat_json_array_add (&vam->json_tree);
4055
4056   vat_json_init_object (node);
4057   if (mp->is_ipv6)
4058     {
4059       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4060       vat_json_object_add_ip6 (node, "map resolver", ip6);
4061     }
4062   else
4063     {
4064       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4065       vat_json_object_add_ip4 (node, "map resolver", ip4);
4066     }
4067 }
4068
4069 static void
4070 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4071 {
4072   vat_main_t *vam = &vat_main;
4073   i32 retval = ntohl (mp->retval);
4074
4075   if (0 <= retval)
4076     {
4077       print (vam->ofp, "feature: %s\ngpe: %s",
4078              mp->feature_status ? "enabled" : "disabled",
4079              mp->gpe_status ? "enabled" : "disabled");
4080     }
4081
4082   vam->retval = retval;
4083   vam->result_ready = 1;
4084 }
4085
4086 static void
4087   vl_api_show_one_status_reply_t_handler_json
4088   (vl_api_show_one_status_reply_t * mp)
4089 {
4090   vat_main_t *vam = &vat_main;
4091   vat_json_node_t node;
4092   u8 *gpe_status = NULL;
4093   u8 *feature_status = NULL;
4094
4095   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4096   feature_status = format (0, "%s",
4097                            mp->feature_status ? "enabled" : "disabled");
4098   vec_add1 (gpe_status, 0);
4099   vec_add1 (feature_status, 0);
4100
4101   vat_json_init_object (&node);
4102   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4103   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4104
4105   vec_free (gpe_status);
4106   vec_free (feature_status);
4107
4108   vat_json_print (vam->ofp, &node);
4109   vat_json_free (&node);
4110
4111   vam->retval = ntohl (mp->retval);
4112   vam->result_ready = 1;
4113 }
4114
4115 static void
4116   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4117   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4118 {
4119   vat_main_t *vam = &vat_main;
4120   i32 retval = ntohl (mp->retval);
4121
4122   if (retval >= 0)
4123     {
4124       print (vam->ofp, "%=20s", mp->locator_set_name);
4125     }
4126
4127   vam->retval = retval;
4128   vam->result_ready = 1;
4129 }
4130
4131 static void
4132   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4133   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   vat_json_node_t *node = NULL;
4137
4138   if (VAT_JSON_ARRAY != vam->json_tree.type)
4139     {
4140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4141       vat_json_init_array (&vam->json_tree);
4142     }
4143   node = vat_json_array_add (&vam->json_tree);
4144
4145   vat_json_init_object (node);
4146   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4147
4148   vat_json_print (vam->ofp, node);
4149   vat_json_free (node);
4150
4151   vam->retval = ntohl (mp->retval);
4152   vam->result_ready = 1;
4153 }
4154
4155 static u8 *
4156 format_lisp_map_request_mode (u8 * s, va_list * args)
4157 {
4158   u32 mode = va_arg (*args, u32);
4159
4160   switch (mode)
4161     {
4162     case 0:
4163       return format (0, "dst-only");
4164     case 1:
4165       return format (0, "src-dst");
4166     }
4167   return 0;
4168 }
4169
4170 static void
4171   vl_api_show_one_map_request_mode_reply_t_handler
4172   (vl_api_show_one_map_request_mode_reply_t * mp)
4173 {
4174   vat_main_t *vam = &vat_main;
4175   i32 retval = ntohl (mp->retval);
4176
4177   if (0 <= retval)
4178     {
4179       u32 mode = mp->mode;
4180       print (vam->ofp, "map_request_mode: %U",
4181              format_lisp_map_request_mode, mode);
4182     }
4183
4184   vam->retval = retval;
4185   vam->result_ready = 1;
4186 }
4187
4188 static void
4189   vl_api_show_one_map_request_mode_reply_t_handler_json
4190   (vl_api_show_one_map_request_mode_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194   u8 *s = 0;
4195   u32 mode;
4196
4197   mode = mp->mode;
4198   s = format (0, "%U", format_lisp_map_request_mode, mode);
4199   vec_add1 (s, 0);
4200
4201   vat_json_init_object (&node);
4202   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4203   vat_json_print (vam->ofp, &node);
4204   vat_json_free (&node);
4205
4206   vec_free (s);
4207   vam->retval = ntohl (mp->retval);
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_show_one_use_petr_reply_t_handler
4213   (vl_api_show_one_use_petr_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   i32 retval = ntohl (mp->retval);
4217
4218   if (0 <= retval)
4219     {
4220       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4221       if (mp->status)
4222         {
4223           print (vam->ofp, "Proxy-ETR address; %U",
4224                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4225                  mp->address);
4226         }
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_show_one_use_petr_reply_t_handler_json
4235   (vl_api_show_one_use_petr_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240   struct in_addr ip4;
4241   struct in6_addr ip6;
4242
4243   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4244   vec_add1 (status, 0);
4245
4246   vat_json_init_object (&node);
4247   vat_json_object_add_string_copy (&node, "status", status);
4248   if (mp->status)
4249     {
4250       if (mp->is_ip4)
4251         {
4252           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4253           vat_json_object_add_ip6 (&node, "address", ip6);
4254         }
4255       else
4256         {
4257           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4258           vat_json_object_add_ip4 (&node, "address", ip4);
4259         }
4260     }
4261
4262   vec_free (status);
4263
4264   vat_json_print (vam->ofp, &node);
4265   vat_json_free (&node);
4266
4267   vam->retval = ntohl (mp->retval);
4268   vam->result_ready = 1;
4269 }
4270
4271 static void
4272   vl_api_show_one_nsh_mapping_reply_t_handler
4273   (vl_api_show_one_nsh_mapping_reply_t * mp)
4274 {
4275   vat_main_t *vam = &vat_main;
4276   i32 retval = ntohl (mp->retval);
4277
4278   if (0 <= retval)
4279     {
4280       print (vam->ofp, "%-20s%-16s",
4281              mp->is_set ? "set" : "not-set",
4282              mp->is_set ? (char *) mp->locator_set_name : "");
4283     }
4284
4285   vam->retval = retval;
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_show_one_nsh_mapping_reply_t_handler_json
4291   (vl_api_show_one_nsh_mapping_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   vat_json_node_t node;
4295   u8 *status = 0;
4296
4297   status = format (0, "%s", mp->is_set ? "yes" : "no");
4298   vec_add1 (status, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "is_set", status);
4302   if (mp->is_set)
4303     {
4304       vat_json_object_add_string_copy (&node, "locator_set",
4305                                        mp->locator_set_name);
4306     }
4307
4308   vec_free (status);
4309
4310   vat_json_print (vam->ofp, &node);
4311   vat_json_free (&node);
4312
4313   vam->retval = ntohl (mp->retval);
4314   vam->result_ready = 1;
4315 }
4316
4317 static void
4318   vl_api_show_one_map_register_ttl_reply_t_handler
4319   (vl_api_show_one_map_register_ttl_reply_t * mp)
4320 {
4321   vat_main_t *vam = &vat_main;
4322   i32 retval = ntohl (mp->retval);
4323
4324   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4325
4326   if (0 <= retval)
4327     {
4328       print (vam->ofp, "ttl: %u", mp->ttl);
4329     }
4330
4331   vam->retval = retval;
4332   vam->result_ready = 1;
4333 }
4334
4335 static void
4336   vl_api_show_one_map_register_ttl_reply_t_handler_json
4337   (vl_api_show_one_map_register_ttl_reply_t * mp)
4338 {
4339   vat_main_t *vam = &vat_main;
4340   vat_json_node_t node;
4341
4342   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4343   vat_json_init_object (&node);
4344   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4345
4346   vat_json_print (vam->ofp, &node);
4347   vat_json_free (&node);
4348
4349   vam->retval = ntohl (mp->retval);
4350   vam->result_ready = 1;
4351 }
4352
4353 static void
4354 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   i32 retval = ntohl (mp->retval);
4358
4359   if (0 <= retval)
4360     {
4361       print (vam->ofp, "%-20s%-16s",
4362              mp->status ? "enabled" : "disabled",
4363              mp->status ? (char *) mp->locator_set_name : "");
4364     }
4365
4366   vam->retval = retval;
4367   vam->result_ready = 1;
4368 }
4369
4370 static void
4371 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4372 {
4373   vat_main_t *vam = &vat_main;
4374   vat_json_node_t node;
4375   u8 *status = 0;
4376
4377   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4378   vec_add1 (status, 0);
4379
4380   vat_json_init_object (&node);
4381   vat_json_object_add_string_copy (&node, "status", status);
4382   if (mp->status)
4383     {
4384       vat_json_object_add_string_copy (&node, "locator_set",
4385                                        mp->locator_set_name);
4386     }
4387
4388   vec_free (status);
4389
4390   vat_json_print (vam->ofp, &node);
4391   vat_json_free (&node);
4392
4393   vam->retval = ntohl (mp->retval);
4394   vam->result_ready = 1;
4395 }
4396
4397 static u8 *
4398 format_policer_type (u8 * s, va_list * va)
4399 {
4400   u32 i = va_arg (*va, u32);
4401
4402   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4403     s = format (s, "1r2c");
4404   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4405     s = format (s, "1r3c");
4406   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4407     s = format (s, "2r3c-2698");
4408   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4409     s = format (s, "2r3c-4115");
4410   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4411     s = format (s, "2r3c-mef5cf1");
4412   else
4413     s = format (s, "ILLEGAL");
4414   return s;
4415 }
4416
4417 static u8 *
4418 format_policer_rate_type (u8 * s, va_list * va)
4419 {
4420   u32 i = va_arg (*va, u32);
4421
4422   if (i == SSE2_QOS_RATE_KBPS)
4423     s = format (s, "kbps");
4424   else if (i == SSE2_QOS_RATE_PPS)
4425     s = format (s, "pps");
4426   else
4427     s = format (s, "ILLEGAL");
4428   return s;
4429 }
4430
4431 static u8 *
4432 format_policer_round_type (u8 * s, va_list * va)
4433 {
4434   u32 i = va_arg (*va, u32);
4435
4436   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4437     s = format (s, "closest");
4438   else if (i == SSE2_QOS_ROUND_TO_UP)
4439     s = format (s, "up");
4440   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4441     s = format (s, "down");
4442   else
4443     s = format (s, "ILLEGAL");
4444   return s;
4445 }
4446
4447 static u8 *
4448 format_policer_action_type (u8 * s, va_list * va)
4449 {
4450   u32 i = va_arg (*va, u32);
4451
4452   if (i == SSE2_QOS_ACTION_DROP)
4453     s = format (s, "drop");
4454   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4455     s = format (s, "transmit");
4456   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4457     s = format (s, "mark-and-transmit");
4458   else
4459     s = format (s, "ILLEGAL");
4460   return s;
4461 }
4462
4463 static u8 *
4464 format_dscp (u8 * s, va_list * va)
4465 {
4466   u32 i = va_arg (*va, u32);
4467   char *t = 0;
4468
4469   switch (i)
4470     {
4471 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4472       foreach_vnet_dscp
4473 #undef _
4474     default:
4475       return format (s, "ILLEGAL");
4476     }
4477   s = format (s, "%s", t);
4478   return s;
4479 }
4480
4481 static void
4482 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4483 {
4484   vat_main_t *vam = &vat_main;
4485   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4486
4487   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4488     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4489   else
4490     conform_dscp_str = format (0, "");
4491
4492   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4493     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4494   else
4495     exceed_dscp_str = format (0, "");
4496
4497   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4498     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4499   else
4500     violate_dscp_str = format (0, "");
4501
4502   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4503          "rate type %U, round type %U, %s rate, %s color-aware, "
4504          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4505          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4506          "conform action %U%s, exceed action %U%s, violate action %U%s",
4507          mp->name,
4508          format_policer_type, mp->type,
4509          ntohl (mp->cir),
4510          ntohl (mp->eir),
4511          clib_net_to_host_u64 (mp->cb),
4512          clib_net_to_host_u64 (mp->eb),
4513          format_policer_rate_type, mp->rate_type,
4514          format_policer_round_type, mp->round_type,
4515          mp->single_rate ? "single" : "dual",
4516          mp->color_aware ? "is" : "not",
4517          ntohl (mp->cir_tokens_per_period),
4518          ntohl (mp->pir_tokens_per_period),
4519          ntohl (mp->scale),
4520          ntohl (mp->current_limit),
4521          ntohl (mp->current_bucket),
4522          ntohl (mp->extended_limit),
4523          ntohl (mp->extended_bucket),
4524          clib_net_to_host_u64 (mp->last_update_time),
4525          format_policer_action_type, mp->conform_action_type,
4526          conform_dscp_str,
4527          format_policer_action_type, mp->exceed_action_type,
4528          exceed_dscp_str,
4529          format_policer_action_type, mp->violate_action_type,
4530          violate_dscp_str);
4531
4532   vec_free (conform_dscp_str);
4533   vec_free (exceed_dscp_str);
4534   vec_free (violate_dscp_str);
4535 }
4536
4537 static void vl_api_policer_details_t_handler_json
4538   (vl_api_policer_details_t * mp)
4539 {
4540   vat_main_t *vam = &vat_main;
4541   vat_json_node_t *node;
4542   u8 *rate_type_str, *round_type_str, *type_str;
4543   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4544
4545   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4546   round_type_str =
4547     format (0, "%U", format_policer_round_type, mp->round_type);
4548   type_str = format (0, "%U", format_policer_type, mp->type);
4549   conform_action_str = format (0, "%U", format_policer_action_type,
4550                                mp->conform_action_type);
4551   exceed_action_str = format (0, "%U", format_policer_action_type,
4552                               mp->exceed_action_type);
4553   violate_action_str = format (0, "%U", format_policer_action_type,
4554                                mp->violate_action_type);
4555
4556   if (VAT_JSON_ARRAY != vam->json_tree.type)
4557     {
4558       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4559       vat_json_init_array (&vam->json_tree);
4560     }
4561   node = vat_json_array_add (&vam->json_tree);
4562
4563   vat_json_init_object (node);
4564   vat_json_object_add_string_copy (node, "name", mp->name);
4565   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4566   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4567   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4568   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4569   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4570   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4571   vat_json_object_add_string_copy (node, "type", type_str);
4572   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4573   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4574   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4575   vat_json_object_add_uint (node, "cir_tokens_per_period",
4576                             ntohl (mp->cir_tokens_per_period));
4577   vat_json_object_add_uint (node, "eir_tokens_per_period",
4578                             ntohl (mp->pir_tokens_per_period));
4579   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4580   vat_json_object_add_uint (node, "current_bucket",
4581                             ntohl (mp->current_bucket));
4582   vat_json_object_add_uint (node, "extended_limit",
4583                             ntohl (mp->extended_limit));
4584   vat_json_object_add_uint (node, "extended_bucket",
4585                             ntohl (mp->extended_bucket));
4586   vat_json_object_add_uint (node, "last_update_time",
4587                             ntohl (mp->last_update_time));
4588   vat_json_object_add_string_copy (node, "conform_action",
4589                                    conform_action_str);
4590   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4591     {
4592       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4593       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4594       vec_free (dscp_str);
4595     }
4596   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4597   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4598     {
4599       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4600       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4601       vec_free (dscp_str);
4602     }
4603   vat_json_object_add_string_copy (node, "violate_action",
4604                                    violate_action_str);
4605   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4606     {
4607       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4608       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4609       vec_free (dscp_str);
4610     }
4611
4612   vec_free (rate_type_str);
4613   vec_free (round_type_str);
4614   vec_free (type_str);
4615   vec_free (conform_action_str);
4616   vec_free (exceed_action_str);
4617   vec_free (violate_action_str);
4618 }
4619
4620 static void
4621 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4622                                            mp)
4623 {
4624   vat_main_t *vam = &vat_main;
4625   int i, count = ntohl (mp->count);
4626
4627   if (count > 0)
4628     print (vam->ofp, "classify table ids (%d) : ", count);
4629   for (i = 0; i < count; i++)
4630     {
4631       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4632       print (vam->ofp, (i < count - 1) ? "," : "");
4633     }
4634   vam->retval = ntohl (mp->retval);
4635   vam->result_ready = 1;
4636 }
4637
4638 static void
4639   vl_api_classify_table_ids_reply_t_handler_json
4640   (vl_api_classify_table_ids_reply_t * mp)
4641 {
4642   vat_main_t *vam = &vat_main;
4643   int i, count = ntohl (mp->count);
4644
4645   if (count > 0)
4646     {
4647       vat_json_node_t node;
4648
4649       vat_json_init_object (&node);
4650       for (i = 0; i < count; i++)
4651         {
4652           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4653         }
4654       vat_json_print (vam->ofp, &node);
4655       vat_json_free (&node);
4656     }
4657   vam->retval = ntohl (mp->retval);
4658   vam->result_ready = 1;
4659 }
4660
4661 static void
4662   vl_api_classify_table_by_interface_reply_t_handler
4663   (vl_api_classify_table_by_interface_reply_t * mp)
4664 {
4665   vat_main_t *vam = &vat_main;
4666   u32 table_id;
4667
4668   table_id = ntohl (mp->l2_table_id);
4669   if (table_id != ~0)
4670     print (vam->ofp, "l2 table id : %d", table_id);
4671   else
4672     print (vam->ofp, "l2 table id : No input ACL tables configured");
4673   table_id = ntohl (mp->ip4_table_id);
4674   if (table_id != ~0)
4675     print (vam->ofp, "ip4 table id : %d", table_id);
4676   else
4677     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4678   table_id = ntohl (mp->ip6_table_id);
4679   if (table_id != ~0)
4680     print (vam->ofp, "ip6 table id : %d", table_id);
4681   else
4682     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4683   vam->retval = ntohl (mp->retval);
4684   vam->result_ready = 1;
4685 }
4686
4687 static void
4688   vl_api_classify_table_by_interface_reply_t_handler_json
4689   (vl_api_classify_table_by_interface_reply_t * mp)
4690 {
4691   vat_main_t *vam = &vat_main;
4692   vat_json_node_t node;
4693
4694   vat_json_init_object (&node);
4695
4696   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4697   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4698   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4699
4700   vat_json_print (vam->ofp, &node);
4701   vat_json_free (&node);
4702
4703   vam->retval = ntohl (mp->retval);
4704   vam->result_ready = 1;
4705 }
4706
4707 static void vl_api_policer_add_del_reply_t_handler
4708   (vl_api_policer_add_del_reply_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   i32 retval = ntohl (mp->retval);
4712   if (vam->async_mode)
4713     {
4714       vam->async_errors += (retval < 0);
4715     }
4716   else
4717     {
4718       vam->retval = retval;
4719       vam->result_ready = 1;
4720       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4721         /*
4722          * Note: this is just barely thread-safe, depends on
4723          * the main thread spinning waiting for an answer...
4724          */
4725         errmsg ("policer index %d", ntohl (mp->policer_index));
4726     }
4727 }
4728
4729 static void vl_api_policer_add_del_reply_t_handler_json
4730   (vl_api_policer_add_del_reply_t * mp)
4731 {
4732   vat_main_t *vam = &vat_main;
4733   vat_json_node_t node;
4734
4735   vat_json_init_object (&node);
4736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4737   vat_json_object_add_uint (&node, "policer_index",
4738                             ntohl (mp->policer_index));
4739
4740   vat_json_print (vam->ofp, &node);
4741   vat_json_free (&node);
4742
4743   vam->retval = ntohl (mp->retval);
4744   vam->result_ready = 1;
4745 }
4746
4747 /* Format hex dump. */
4748 u8 *
4749 format_hex_bytes (u8 * s, va_list * va)
4750 {
4751   u8 *bytes = va_arg (*va, u8 *);
4752   int n_bytes = va_arg (*va, int);
4753   uword i;
4754
4755   /* Print short or long form depending on byte count. */
4756   uword short_form = n_bytes <= 32;
4757   u32 indent = format_get_indent (s);
4758
4759   if (n_bytes == 0)
4760     return s;
4761
4762   for (i = 0; i < n_bytes; i++)
4763     {
4764       if (!short_form && (i % 32) == 0)
4765         s = format (s, "%08x: ", i);
4766       s = format (s, "%02x", bytes[i]);
4767       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4768         s = format (s, "\n%U", format_white_space, indent);
4769     }
4770
4771   return s;
4772 }
4773
4774 static void
4775 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4776                                             * mp)
4777 {
4778   vat_main_t *vam = &vat_main;
4779   i32 retval = ntohl (mp->retval);
4780   if (retval == 0)
4781     {
4782       print (vam->ofp, "classify table info :");
4783       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4784              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4785              ntohl (mp->miss_next_index));
4786       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4787              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4788              ntohl (mp->match_n_vectors));
4789       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4790              ntohl (mp->mask_length));
4791     }
4792   vam->retval = retval;
4793   vam->result_ready = 1;
4794 }
4795
4796 static void
4797   vl_api_classify_table_info_reply_t_handler_json
4798   (vl_api_classify_table_info_reply_t * mp)
4799 {
4800   vat_main_t *vam = &vat_main;
4801   vat_json_node_t node;
4802
4803   i32 retval = ntohl (mp->retval);
4804   if (retval == 0)
4805     {
4806       vat_json_init_object (&node);
4807
4808       vat_json_object_add_int (&node, "sessions",
4809                                ntohl (mp->active_sessions));
4810       vat_json_object_add_int (&node, "nexttbl",
4811                                ntohl (mp->next_table_index));
4812       vat_json_object_add_int (&node, "nextnode",
4813                                ntohl (mp->miss_next_index));
4814       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4815       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4816       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4817       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4818                       ntohl (mp->mask_length), 0);
4819       vat_json_object_add_string_copy (&node, "mask", s);
4820
4821       vat_json_print (vam->ofp, &node);
4822       vat_json_free (&node);
4823     }
4824   vam->retval = ntohl (mp->retval);
4825   vam->result_ready = 1;
4826 }
4827
4828 static void
4829 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4830                                            mp)
4831 {
4832   vat_main_t *vam = &vat_main;
4833
4834   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4835          ntohl (mp->hit_next_index), ntohl (mp->advance),
4836          ntohl (mp->opaque_index));
4837   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4838          ntohl (mp->match_length));
4839 }
4840
4841 static void
4842   vl_api_classify_session_details_t_handler_json
4843   (vl_api_classify_session_details_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t *node = NULL;
4847
4848   if (VAT_JSON_ARRAY != vam->json_tree.type)
4849     {
4850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4851       vat_json_init_array (&vam->json_tree);
4852     }
4853   node = vat_json_array_add (&vam->json_tree);
4854
4855   vat_json_init_object (node);
4856   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4857   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4858   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4859   u8 *s =
4860     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4861             0);
4862   vat_json_object_add_string_copy (node, "match", s);
4863 }
4864
4865 static void vl_api_pg_create_interface_reply_t_handler
4866   (vl_api_pg_create_interface_reply_t * mp)
4867 {
4868   vat_main_t *vam = &vat_main;
4869
4870   vam->retval = ntohl (mp->retval);
4871   vam->result_ready = 1;
4872 }
4873
4874 static void vl_api_pg_create_interface_reply_t_handler_json
4875   (vl_api_pg_create_interface_reply_t * mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878   vat_json_node_t node;
4879
4880   i32 retval = ntohl (mp->retval);
4881   if (retval == 0)
4882     {
4883       vat_json_init_object (&node);
4884
4885       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4886
4887       vat_json_print (vam->ofp, &node);
4888       vat_json_free (&node);
4889     }
4890   vam->retval = ntohl (mp->retval);
4891   vam->result_ready = 1;
4892 }
4893
4894 static void vl_api_policer_classify_details_t_handler
4895   (vl_api_policer_classify_details_t * mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898
4899   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4900          ntohl (mp->table_index));
4901 }
4902
4903 static void vl_api_policer_classify_details_t_handler_json
4904   (vl_api_policer_classify_details_t * mp)
4905 {
4906   vat_main_t *vam = &vat_main;
4907   vat_json_node_t *node;
4908
4909   if (VAT_JSON_ARRAY != vam->json_tree.type)
4910     {
4911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4912       vat_json_init_array (&vam->json_tree);
4913     }
4914   node = vat_json_array_add (&vam->json_tree);
4915
4916   vat_json_init_object (node);
4917   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4918   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4919 }
4920
4921 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4922   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4923 {
4924   vat_main_t *vam = &vat_main;
4925   i32 retval = ntohl (mp->retval);
4926   if (vam->async_mode)
4927     {
4928       vam->async_errors += (retval < 0);
4929     }
4930   else
4931     {
4932       vam->retval = retval;
4933       vam->sw_if_index = ntohl (mp->sw_if_index);
4934       vam->result_ready = 1;
4935     }
4936 }
4937
4938 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4939   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   vat_json_node_t node;
4943
4944   vat_json_init_object (&node);
4945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4946   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4947
4948   vat_json_print (vam->ofp, &node);
4949   vat_json_free (&node);
4950
4951   vam->retval = ntohl (mp->retval);
4952   vam->result_ready = 1;
4953 }
4954
4955 static void vl_api_flow_classify_details_t_handler
4956   (vl_api_flow_classify_details_t * mp)
4957 {
4958   vat_main_t *vam = &vat_main;
4959
4960   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4961          ntohl (mp->table_index));
4962 }
4963
4964 static void vl_api_flow_classify_details_t_handler_json
4965   (vl_api_flow_classify_details_t * mp)
4966 {
4967   vat_main_t *vam = &vat_main;
4968   vat_json_node_t *node;
4969
4970   if (VAT_JSON_ARRAY != vam->json_tree.type)
4971     {
4972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4973       vat_json_init_array (&vam->json_tree);
4974     }
4975   node = vat_json_array_add (&vam->json_tree);
4976
4977   vat_json_init_object (node);
4978   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4979   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4980 }
4981
4982 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4983 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4984 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4985 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4986 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4987 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4988 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4989 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4990 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4991 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4992 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4993 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4994 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4995 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4996 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4997 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4998 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4999 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5000 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5001 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5002 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5003 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5004
5005 /*
5006  * Generate boilerplate reply handlers, which
5007  * dig the return value out of the xxx_reply_t API message,
5008  * stick it into vam->retval, and set vam->result_ready
5009  *
5010  * Could also do this by pointing N message decode slots at
5011  * a single function, but that could break in subtle ways.
5012  */
5013
5014 #define foreach_standard_reply_retval_handler           \
5015 _(sw_interface_set_flags_reply)                         \
5016 _(sw_interface_add_del_address_reply)                   \
5017 _(sw_interface_set_table_reply)                         \
5018 _(sw_interface_set_mpls_enable_reply)                   \
5019 _(sw_interface_set_vpath_reply)                         \
5020 _(sw_interface_set_vxlan_bypass_reply)                  \
5021 _(sw_interface_set_geneve_bypass_reply)                 \
5022 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5023 _(sw_interface_set_l2_bridge_reply)                     \
5024 _(bridge_domain_add_del_reply)                          \
5025 _(sw_interface_set_l2_xconnect_reply)                   \
5026 _(l2fib_add_del_reply)                                  \
5027 _(l2fib_flush_int_reply)                                \
5028 _(l2fib_flush_bd_reply)                                 \
5029 _(ip_add_del_route_reply)                               \
5030 _(ip_table_add_del_reply)                               \
5031 _(ip_mroute_add_del_reply)                              \
5032 _(mpls_route_add_del_reply)                             \
5033 _(mpls_table_add_del_reply)                             \
5034 _(mpls_ip_bind_unbind_reply)                            \
5035 _(proxy_arp_add_del_reply)                              \
5036 _(proxy_arp_intfc_enable_disable_reply)                 \
5037 _(sw_interface_set_unnumbered_reply)                    \
5038 _(ip_neighbor_add_del_reply)                            \
5039 _(reset_vrf_reply)                                      \
5040 _(oam_add_del_reply)                                    \
5041 _(reset_fib_reply)                                      \
5042 _(dhcp_proxy_config_reply)                              \
5043 _(dhcp_proxy_set_vss_reply)                             \
5044 _(dhcp_client_config_reply)                             \
5045 _(set_ip_flow_hash_reply)                               \
5046 _(sw_interface_ip6_enable_disable_reply)                \
5047 _(sw_interface_ip6_set_link_local_address_reply)        \
5048 _(ip6nd_proxy_add_del_reply)                            \
5049 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5050 _(sw_interface_ip6nd_ra_config_reply)                   \
5051 _(set_arp_neighbor_limit_reply)                         \
5052 _(l2_patch_add_del_reply)                               \
5053 _(sr_policy_add_reply)                                  \
5054 _(sr_policy_mod_reply)                                  \
5055 _(sr_policy_del_reply)                                  \
5056 _(sr_localsid_add_del_reply)                            \
5057 _(sr_steering_add_del_reply)                            \
5058 _(classify_add_del_session_reply)                       \
5059 _(classify_set_interface_ip_table_reply)                \
5060 _(classify_set_interface_l2_tables_reply)               \
5061 _(l2tpv3_set_tunnel_cookies_reply)                      \
5062 _(l2tpv3_interface_enable_disable_reply)                \
5063 _(l2tpv3_set_lookup_key_reply)                          \
5064 _(l2_fib_clear_table_reply)                             \
5065 _(l2_interface_efp_filter_reply)                        \
5066 _(l2_interface_vlan_tag_rewrite_reply)                  \
5067 _(modify_vhost_user_if_reply)                           \
5068 _(delete_vhost_user_if_reply)                           \
5069 _(want_ip4_arp_events_reply)                            \
5070 _(want_ip6_nd_events_reply)                             \
5071 _(want_l2_macs_events_reply)                            \
5072 _(input_acl_set_interface_reply)                        \
5073 _(ipsec_spd_add_del_reply)                              \
5074 _(ipsec_interface_add_del_spd_reply)                    \
5075 _(ipsec_spd_add_del_entry_reply)                        \
5076 _(ipsec_sad_add_del_entry_reply)                        \
5077 _(ipsec_sa_set_key_reply)                               \
5078 _(ipsec_tunnel_if_add_del_reply)                        \
5079 _(ipsec_tunnel_if_set_key_reply)                        \
5080 _(ikev2_profile_add_del_reply)                          \
5081 _(ikev2_profile_set_auth_reply)                         \
5082 _(ikev2_profile_set_id_reply)                           \
5083 _(ikev2_profile_set_ts_reply)                           \
5084 _(ikev2_set_local_key_reply)                            \
5085 _(ikev2_set_responder_reply)                            \
5086 _(ikev2_set_ike_transforms_reply)                       \
5087 _(ikev2_set_esp_transforms_reply)                       \
5088 _(ikev2_set_sa_lifetime_reply)                          \
5089 _(ikev2_initiate_sa_init_reply)                         \
5090 _(ikev2_initiate_del_ike_sa_reply)                      \
5091 _(ikev2_initiate_del_child_sa_reply)                    \
5092 _(ikev2_initiate_rekey_child_sa_reply)                  \
5093 _(delete_loopback_reply)                                \
5094 _(bd_ip_mac_add_del_reply)                              \
5095 _(map_del_domain_reply)                                 \
5096 _(map_add_del_rule_reply)                               \
5097 _(want_interface_events_reply)                          \
5098 _(want_stats_reply)                                     \
5099 _(cop_interface_enable_disable_reply)                   \
5100 _(cop_whitelist_enable_disable_reply)                   \
5101 _(sw_interface_clear_stats_reply)                       \
5102 _(ioam_enable_reply)                                    \
5103 _(ioam_disable_reply)                                   \
5104 _(one_add_del_locator_reply)                            \
5105 _(one_add_del_local_eid_reply)                          \
5106 _(one_add_del_remote_mapping_reply)                     \
5107 _(one_add_del_adjacency_reply)                          \
5108 _(one_add_del_map_resolver_reply)                       \
5109 _(one_add_del_map_server_reply)                         \
5110 _(one_enable_disable_reply)                             \
5111 _(one_rloc_probe_enable_disable_reply)                  \
5112 _(one_map_register_enable_disable_reply)                \
5113 _(one_map_register_set_ttl_reply)                       \
5114 _(one_set_transport_protocol_reply)                     \
5115 _(one_map_register_fallback_threshold_reply)            \
5116 _(one_pitr_set_locator_set_reply)                       \
5117 _(one_map_request_mode_reply)                           \
5118 _(one_add_del_map_request_itr_rlocs_reply)              \
5119 _(one_eid_table_add_del_map_reply)                      \
5120 _(one_use_petr_reply)                                   \
5121 _(one_stats_enable_disable_reply)                       \
5122 _(one_add_del_l2_arp_entry_reply)                       \
5123 _(one_add_del_ndp_entry_reply)                          \
5124 _(one_stats_flush_reply)                                \
5125 _(gpe_enable_disable_reply)                             \
5126 _(gpe_set_encap_mode_reply)                             \
5127 _(gpe_add_del_iface_reply)                              \
5128 _(gpe_add_del_native_fwd_rpath_reply)                   \
5129 _(af_packet_delete_reply)                               \
5130 _(policer_classify_set_interface_reply)                 \
5131 _(netmap_create_reply)                                  \
5132 _(netmap_delete_reply)                                  \
5133 _(set_ipfix_exporter_reply)                             \
5134 _(set_ipfix_classify_stream_reply)                      \
5135 _(ipfix_classify_table_add_del_reply)                   \
5136 _(flow_classify_set_interface_reply)                    \
5137 _(sw_interface_span_enable_disable_reply)               \
5138 _(pg_capture_reply)                                     \
5139 _(pg_enable_disable_reply)                              \
5140 _(ip_source_and_port_range_check_add_del_reply)         \
5141 _(ip_source_and_port_range_check_interface_add_del_reply)\
5142 _(delete_subif_reply)                                   \
5143 _(l2_interface_pbb_tag_rewrite_reply)                   \
5144 _(punt_reply)                                           \
5145 _(feature_enable_disable_reply)                         \
5146 _(sw_interface_tag_add_del_reply)                       \
5147 _(sw_interface_set_mtu_reply)                           \
5148 _(p2p_ethernet_add_reply)                               \
5149 _(p2p_ethernet_del_reply)                               \
5150 _(lldp_config_reply)                                    \
5151 _(sw_interface_set_lldp_reply)                          \
5152 _(tcp_configure_src_addresses_reply)                    \
5153 _(app_namespace_add_del_reply)                          \
5154 _(dns_enable_disable_reply)                             \
5155 _(dns_name_server_add_del_reply)
5156
5157 #define _(n)                                    \
5158     static void vl_api_##n##_t_handler          \
5159     (vl_api_##n##_t * mp)                       \
5160     {                                           \
5161         vat_main_t * vam = &vat_main;           \
5162         i32 retval = ntohl(mp->retval);         \
5163         if (vam->async_mode) {                  \
5164             vam->async_errors += (retval < 0);  \
5165         } else {                                \
5166             vam->retval = retval;               \
5167             vam->result_ready = 1;              \
5168         }                                       \
5169     }
5170 foreach_standard_reply_retval_handler;
5171 #undef _
5172
5173 #define _(n)                                    \
5174     static void vl_api_##n##_t_handler_json     \
5175     (vl_api_##n##_t * mp)                       \
5176     {                                           \
5177         vat_main_t * vam = &vat_main;           \
5178         vat_json_node_t node;                   \
5179         vat_json_init_object(&node);            \
5180         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5181         vat_json_print(vam->ofp, &node);        \
5182         vam->retval = ntohl(mp->retval);        \
5183         vam->result_ready = 1;                  \
5184     }
5185 foreach_standard_reply_retval_handler;
5186 #undef _
5187
5188 /*
5189  * Table of message reply handlers, must include boilerplate handlers
5190  * we just generated
5191  */
5192
5193 #define foreach_vpe_api_reply_msg                                       \
5194 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5195 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5196 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5197 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5198 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5199 _(CLI_REPLY, cli_reply)                                                 \
5200 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5201 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5202   sw_interface_add_del_address_reply)                                   \
5203 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5204 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5205 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5206 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5207 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5208 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5209 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5210   sw_interface_set_l2_xconnect_reply)                                   \
5211 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5212   sw_interface_set_l2_bridge_reply)                                     \
5213 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5214 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5215 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5216 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5217 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5218 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5219 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5220 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5221 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5222 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5223 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5224 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5225 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5226 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5227 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5228 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5229 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5230 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5231 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5232 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5233   proxy_arp_intfc_enable_disable_reply)                                 \
5234 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5235 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5236   sw_interface_set_unnumbered_reply)                                    \
5237 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5238 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5239 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5240 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5241 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5242 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5243 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5244 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5245 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5246 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5247 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5248 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5249   sw_interface_ip6_enable_disable_reply)                                \
5250 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5251   sw_interface_ip6_set_link_local_address_reply)                        \
5252 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5253 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5254 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5255   sw_interface_ip6nd_ra_prefix_reply)                                   \
5256 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5257   sw_interface_ip6nd_ra_config_reply)                                   \
5258 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5259 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5260 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5261 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5262 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5263 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5264 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5265 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5266 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5267 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5268 classify_set_interface_ip_table_reply)                                  \
5269 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5270   classify_set_interface_l2_tables_reply)                               \
5271 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5272 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5273 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5274 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5275 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5276   l2tpv3_interface_enable_disable_reply)                                \
5277 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5278 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5279 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5280 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5281 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5282 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5283 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5284 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5285 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5286 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5287 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5288 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5289 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5290 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5291 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5292 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5293 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5294 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5295 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5296 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5297 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5298 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5299 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5300 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5301 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5302 _(L2_MACS_EVENT, l2_macs_event)                                         \
5303 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5304 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5305 _(IP_DETAILS, ip_details)                                               \
5306 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5307 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5308 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5309 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5310 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5311 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5312 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5313 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5314 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5315 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5316 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5317 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5318 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5319 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5320 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5321 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5322 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5323 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5324 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5325 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5326 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5327 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5328 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5329 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5330 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5331 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5332 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5333 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5334 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5335 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5336 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5337 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5338 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5339 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5340 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5341 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5342 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5343 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5344 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5345 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5346 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5347 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5348 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5349 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5350 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5351 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5352 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5353   one_map_register_enable_disable_reply)                                \
5354 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5355 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5356 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5357 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5358   one_map_register_fallback_threshold_reply)                            \
5359 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5360   one_rloc_probe_enable_disable_reply)                                  \
5361 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5362 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5363 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5364 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5365 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5366 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5367 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5368 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5369 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5370 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5371 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5372 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5373 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5374 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5375 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5376 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5377   show_one_stats_enable_disable_reply)                                  \
5378 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5379 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5380 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5381 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5382 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5383 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5384 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5385 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5386 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5387 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5388 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5389 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5390 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5391 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5392 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5393   gpe_add_del_native_fwd_rpath_reply)                                   \
5394 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5395   gpe_fwd_entry_path_details)                                           \
5396 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5397 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5398   one_add_del_map_request_itr_rlocs_reply)                              \
5399 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5400   one_get_map_request_itr_rlocs_reply)                                  \
5401 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5402 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5403 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5404 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5405 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5406 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5407   show_one_map_register_state_reply)                                    \
5408 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5409 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5410   show_one_map_register_fallback_threshold_reply)                       \
5411 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5412 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5413 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5414 _(POLICER_DETAILS, policer_details)                                     \
5415 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5416 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5417 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5418 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5419 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5420 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5421 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5422 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5423 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5424 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5425 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5426 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5427 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5428 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5429 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5430 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5431 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5432 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5433 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5434 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5435 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5436 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5437 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5438 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5439 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5440  ip_source_and_port_range_check_add_del_reply)                          \
5441 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5442  ip_source_and_port_range_check_interface_add_del_reply)                \
5443 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5444 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5445 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5446 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5447 _(PUNT_REPLY, punt_reply)                                               \
5448 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5449 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5450 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5451 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5452 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5453 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5454 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5455 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5456 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5457 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5458 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5459 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5460 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5461 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5462 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5463 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5464 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)
5465
5466 #define foreach_standalone_reply_msg                                    \
5467 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5468 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5469 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5470 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5471 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5472 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5473 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5474 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5475
5476 typedef struct
5477 {
5478   u8 *name;
5479   u32 value;
5480 } name_sort_t;
5481
5482
5483 #define STR_VTR_OP_CASE(op)     \
5484     case L2_VTR_ ## op:         \
5485         return "" # op;
5486
5487 static const char *
5488 str_vtr_op (u32 vtr_op)
5489 {
5490   switch (vtr_op)
5491     {
5492       STR_VTR_OP_CASE (DISABLED);
5493       STR_VTR_OP_CASE (PUSH_1);
5494       STR_VTR_OP_CASE (PUSH_2);
5495       STR_VTR_OP_CASE (POP_1);
5496       STR_VTR_OP_CASE (POP_2);
5497       STR_VTR_OP_CASE (TRANSLATE_1_1);
5498       STR_VTR_OP_CASE (TRANSLATE_1_2);
5499       STR_VTR_OP_CASE (TRANSLATE_2_1);
5500       STR_VTR_OP_CASE (TRANSLATE_2_2);
5501     }
5502
5503   return "UNKNOWN";
5504 }
5505
5506 static int
5507 dump_sub_interface_table (vat_main_t * vam)
5508 {
5509   const sw_interface_subif_t *sub = NULL;
5510
5511   if (vam->json_output)
5512     {
5513       clib_warning
5514         ("JSON output supported only for VPE API calls and dump_stats_table");
5515       return -99;
5516     }
5517
5518   print (vam->ofp,
5519          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5520          "Interface", "sw_if_index",
5521          "sub id", "dot1ad", "tags", "outer id",
5522          "inner id", "exact", "default", "outer any", "inner any");
5523
5524   vec_foreach (sub, vam->sw_if_subif_table)
5525   {
5526     print (vam->ofp,
5527            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5528            sub->interface_name,
5529            sub->sw_if_index,
5530            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5531            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5532            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5533            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5534     if (sub->vtr_op != L2_VTR_DISABLED)
5535       {
5536         print (vam->ofp,
5537                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5538                "tag1: %d tag2: %d ]",
5539                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5540                sub->vtr_tag1, sub->vtr_tag2);
5541       }
5542   }
5543
5544   return 0;
5545 }
5546
5547 static int
5548 name_sort_cmp (void *a1, void *a2)
5549 {
5550   name_sort_t *n1 = a1;
5551   name_sort_t *n2 = a2;
5552
5553   return strcmp ((char *) n1->name, (char *) n2->name);
5554 }
5555
5556 static int
5557 dump_interface_table (vat_main_t * vam)
5558 {
5559   hash_pair_t *p;
5560   name_sort_t *nses = 0, *ns;
5561
5562   if (vam->json_output)
5563     {
5564       clib_warning
5565         ("JSON output supported only for VPE API calls and dump_stats_table");
5566       return -99;
5567     }
5568
5569   /* *INDENT-OFF* */
5570   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5571   ({
5572     vec_add2 (nses, ns, 1);
5573     ns->name = (u8 *)(p->key);
5574     ns->value = (u32) p->value[0];
5575   }));
5576   /* *INDENT-ON* */
5577
5578   vec_sort_with_function (nses, name_sort_cmp);
5579
5580   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5581   vec_foreach (ns, nses)
5582   {
5583     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5584   }
5585   vec_free (nses);
5586   return 0;
5587 }
5588
5589 static int
5590 dump_ip_table (vat_main_t * vam, int is_ipv6)
5591 {
5592   const ip_details_t *det = NULL;
5593   const ip_address_details_t *address = NULL;
5594   u32 i = ~0;
5595
5596   print (vam->ofp, "%-12s", "sw_if_index");
5597
5598   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5599   {
5600     i++;
5601     if (!det->present)
5602       {
5603         continue;
5604       }
5605     print (vam->ofp, "%-12d", i);
5606     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5607     if (!det->addr)
5608       {
5609         continue;
5610       }
5611     vec_foreach (address, det->addr)
5612     {
5613       print (vam->ofp,
5614              "            %-30U%-13d",
5615              is_ipv6 ? format_ip6_address : format_ip4_address,
5616              address->ip, address->prefix_length);
5617     }
5618   }
5619
5620   return 0;
5621 }
5622
5623 static int
5624 dump_ipv4_table (vat_main_t * vam)
5625 {
5626   if (vam->json_output)
5627     {
5628       clib_warning
5629         ("JSON output supported only for VPE API calls and dump_stats_table");
5630       return -99;
5631     }
5632
5633   return dump_ip_table (vam, 0);
5634 }
5635
5636 static int
5637 dump_ipv6_table (vat_main_t * vam)
5638 {
5639   if (vam->json_output)
5640     {
5641       clib_warning
5642         ("JSON output supported only for VPE API calls and dump_stats_table");
5643       return -99;
5644     }
5645
5646   return dump_ip_table (vam, 1);
5647 }
5648
5649 static char *
5650 counter_type_to_str (u8 counter_type, u8 is_combined)
5651 {
5652   if (!is_combined)
5653     {
5654       switch (counter_type)
5655         {
5656         case VNET_INTERFACE_COUNTER_DROP:
5657           return "drop";
5658         case VNET_INTERFACE_COUNTER_PUNT:
5659           return "punt";
5660         case VNET_INTERFACE_COUNTER_IP4:
5661           return "ip4";
5662         case VNET_INTERFACE_COUNTER_IP6:
5663           return "ip6";
5664         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5665           return "rx-no-buf";
5666         case VNET_INTERFACE_COUNTER_RX_MISS:
5667           return "rx-miss";
5668         case VNET_INTERFACE_COUNTER_RX_ERROR:
5669           return "rx-error";
5670         case VNET_INTERFACE_COUNTER_TX_ERROR:
5671           return "tx-error";
5672         default:
5673           return "INVALID-COUNTER-TYPE";
5674         }
5675     }
5676   else
5677     {
5678       switch (counter_type)
5679         {
5680         case VNET_INTERFACE_COUNTER_RX:
5681           return "rx";
5682         case VNET_INTERFACE_COUNTER_TX:
5683           return "tx";
5684         default:
5685           return "INVALID-COUNTER-TYPE";
5686         }
5687     }
5688 }
5689
5690 static int
5691 dump_stats_table (vat_main_t * vam)
5692 {
5693   vat_json_node_t node;
5694   vat_json_node_t *msg_array;
5695   vat_json_node_t *msg;
5696   vat_json_node_t *counter_array;
5697   vat_json_node_t *counter;
5698   interface_counter_t c;
5699   u64 packets;
5700   ip4_fib_counter_t *c4;
5701   ip6_fib_counter_t *c6;
5702   ip4_nbr_counter_t *n4;
5703   ip6_nbr_counter_t *n6;
5704   int i, j;
5705
5706   if (!vam->json_output)
5707     {
5708       clib_warning ("dump_stats_table supported only in JSON format");
5709       return -99;
5710     }
5711
5712   vat_json_init_object (&node);
5713
5714   /* interface counters */
5715   msg_array = vat_json_object_add (&node, "interface_counters");
5716   vat_json_init_array (msg_array);
5717   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5718     {
5719       msg = vat_json_array_add (msg_array);
5720       vat_json_init_object (msg);
5721       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5722                                        (u8 *) counter_type_to_str (i, 0));
5723       vat_json_object_add_int (msg, "is_combined", 0);
5724       counter_array = vat_json_object_add (msg, "data");
5725       vat_json_init_array (counter_array);
5726       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5727         {
5728           packets = vam->simple_interface_counters[i][j];
5729           vat_json_array_add_uint (counter_array, packets);
5730         }
5731     }
5732   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5733     {
5734       msg = vat_json_array_add (msg_array);
5735       vat_json_init_object (msg);
5736       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5737                                        (u8 *) counter_type_to_str (i, 1));
5738       vat_json_object_add_int (msg, "is_combined", 1);
5739       counter_array = vat_json_object_add (msg, "data");
5740       vat_json_init_array (counter_array);
5741       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5742         {
5743           c = vam->combined_interface_counters[i][j];
5744           counter = vat_json_array_add (counter_array);
5745           vat_json_init_object (counter);
5746           vat_json_object_add_uint (counter, "packets", c.packets);
5747           vat_json_object_add_uint (counter, "bytes", c.bytes);
5748         }
5749     }
5750
5751   /* ip4 fib counters */
5752   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5753   vat_json_init_array (msg_array);
5754   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5755     {
5756       msg = vat_json_array_add (msg_array);
5757       vat_json_init_object (msg);
5758       vat_json_object_add_uint (msg, "vrf_id",
5759                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5760       counter_array = vat_json_object_add (msg, "c");
5761       vat_json_init_array (counter_array);
5762       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5763         {
5764           counter = vat_json_array_add (counter_array);
5765           vat_json_init_object (counter);
5766           c4 = &vam->ip4_fib_counters[i][j];
5767           vat_json_object_add_ip4 (counter, "address", c4->address);
5768           vat_json_object_add_uint (counter, "address_length",
5769                                     c4->address_length);
5770           vat_json_object_add_uint (counter, "packets", c4->packets);
5771           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5772         }
5773     }
5774
5775   /* ip6 fib counters */
5776   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5777   vat_json_init_array (msg_array);
5778   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5779     {
5780       msg = vat_json_array_add (msg_array);
5781       vat_json_init_object (msg);
5782       vat_json_object_add_uint (msg, "vrf_id",
5783                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5784       counter_array = vat_json_object_add (msg, "c");
5785       vat_json_init_array (counter_array);
5786       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5787         {
5788           counter = vat_json_array_add (counter_array);
5789           vat_json_init_object (counter);
5790           c6 = &vam->ip6_fib_counters[i][j];
5791           vat_json_object_add_ip6 (counter, "address", c6->address);
5792           vat_json_object_add_uint (counter, "address_length",
5793                                     c6->address_length);
5794           vat_json_object_add_uint (counter, "packets", c6->packets);
5795           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5796         }
5797     }
5798
5799   /* ip4 nbr counters */
5800   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5801   vat_json_init_array (msg_array);
5802   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5803     {
5804       msg = vat_json_array_add (msg_array);
5805       vat_json_init_object (msg);
5806       vat_json_object_add_uint (msg, "sw_if_index", i);
5807       counter_array = vat_json_object_add (msg, "c");
5808       vat_json_init_array (counter_array);
5809       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5810         {
5811           counter = vat_json_array_add (counter_array);
5812           vat_json_init_object (counter);
5813           n4 = &vam->ip4_nbr_counters[i][j];
5814           vat_json_object_add_ip4 (counter, "address", n4->address);
5815           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5816           vat_json_object_add_uint (counter, "packets", n4->packets);
5817           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5818         }
5819     }
5820
5821   /* ip6 nbr counters */
5822   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5823   vat_json_init_array (msg_array);
5824   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5825     {
5826       msg = vat_json_array_add (msg_array);
5827       vat_json_init_object (msg);
5828       vat_json_object_add_uint (msg, "sw_if_index", i);
5829       counter_array = vat_json_object_add (msg, "c");
5830       vat_json_init_array (counter_array);
5831       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5832         {
5833           counter = vat_json_array_add (counter_array);
5834           vat_json_init_object (counter);
5835           n6 = &vam->ip6_nbr_counters[i][j];
5836           vat_json_object_add_ip6 (counter, "address", n6->address);
5837           vat_json_object_add_uint (counter, "packets", n6->packets);
5838           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5839         }
5840     }
5841
5842   vat_json_print (vam->ofp, &node);
5843   vat_json_free (&node);
5844
5845   return 0;
5846 }
5847
5848 /*
5849  * Pass CLI buffers directly in the CLI_INBAND API message,
5850  * instead of an additional shared memory area.
5851  */
5852 static int
5853 exec_inband (vat_main_t * vam)
5854 {
5855   vl_api_cli_inband_t *mp;
5856   unformat_input_t *i = vam->input;
5857   int ret;
5858
5859   if (vec_len (i->buffer) == 0)
5860     return -1;
5861
5862   if (vam->exec_mode == 0 && unformat (i, "mode"))
5863     {
5864       vam->exec_mode = 1;
5865       return 0;
5866     }
5867   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5868     {
5869       vam->exec_mode = 0;
5870       return 0;
5871     }
5872
5873   /*
5874    * In order for the CLI command to work, it
5875    * must be a vector ending in \n, not a C-string ending
5876    * in \n\0.
5877    */
5878   u32 len = vec_len (vam->input->buffer);
5879   M2 (CLI_INBAND, mp, len);
5880   clib_memcpy (mp->cmd, vam->input->buffer, len);
5881   mp->length = htonl (len);
5882
5883   S (mp);
5884   W (ret);
5885   /* json responses may or may not include a useful reply... */
5886   if (vec_len (vam->cmd_reply))
5887     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5888   return ret;
5889 }
5890
5891 int
5892 exec (vat_main_t * vam)
5893 {
5894   return exec_inband (vam);
5895 }
5896
5897 static int
5898 api_create_loopback (vat_main_t * vam)
5899 {
5900   unformat_input_t *i = vam->input;
5901   vl_api_create_loopback_t *mp;
5902   vl_api_create_loopback_instance_t *mp_lbi;
5903   u8 mac_address[6];
5904   u8 mac_set = 0;
5905   u8 is_specified = 0;
5906   u32 user_instance = 0;
5907   int ret;
5908
5909   memset (mac_address, 0, sizeof (mac_address));
5910
5911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5912     {
5913       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5914         mac_set = 1;
5915       if (unformat (i, "instance %d", &user_instance))
5916         is_specified = 1;
5917       else
5918         break;
5919     }
5920
5921   if (is_specified)
5922     {
5923       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5924       mp_lbi->is_specified = is_specified;
5925       if (is_specified)
5926         mp_lbi->user_instance = htonl (user_instance);
5927       if (mac_set)
5928         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5929       S (mp_lbi);
5930     }
5931   else
5932     {
5933       /* Construct the API message */
5934       M (CREATE_LOOPBACK, mp);
5935       if (mac_set)
5936         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5937       S (mp);
5938     }
5939
5940   W (ret);
5941   return ret;
5942 }
5943
5944 static int
5945 api_delete_loopback (vat_main_t * vam)
5946 {
5947   unformat_input_t *i = vam->input;
5948   vl_api_delete_loopback_t *mp;
5949   u32 sw_if_index = ~0;
5950   int ret;
5951
5952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5953     {
5954       if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         ;
5956       else
5957         break;
5958     }
5959
5960   if (sw_if_index == ~0)
5961     {
5962       errmsg ("missing sw_if_index");
5963       return -99;
5964     }
5965
5966   /* Construct the API message */
5967   M (DELETE_LOOPBACK, mp);
5968   mp->sw_if_index = ntohl (sw_if_index);
5969
5970   S (mp);
5971   W (ret);
5972   return ret;
5973 }
5974
5975 static int
5976 api_want_stats (vat_main_t * vam)
5977 {
5978   unformat_input_t *i = vam->input;
5979   vl_api_want_stats_t *mp;
5980   int enable = -1;
5981   int ret;
5982
5983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5984     {
5985       if (unformat (i, "enable"))
5986         enable = 1;
5987       else if (unformat (i, "disable"))
5988         enable = 0;
5989       else
5990         break;
5991     }
5992
5993   if (enable == -1)
5994     {
5995       errmsg ("missing enable|disable");
5996       return -99;
5997     }
5998
5999   M (WANT_STATS, mp);
6000   mp->enable_disable = enable;
6001
6002   S (mp);
6003   W (ret);
6004   return ret;
6005 }
6006
6007 static int
6008 api_want_interface_events (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_want_interface_events_t *mp;
6012   int enable = -1;
6013   int ret;
6014
6015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6016     {
6017       if (unformat (i, "enable"))
6018         enable = 1;
6019       else if (unformat (i, "disable"))
6020         enable = 0;
6021       else
6022         break;
6023     }
6024
6025   if (enable == -1)
6026     {
6027       errmsg ("missing enable|disable");
6028       return -99;
6029     }
6030
6031   M (WANT_INTERFACE_EVENTS, mp);
6032   mp->enable_disable = enable;
6033
6034   vam->interface_event_display = enable;
6035
6036   S (mp);
6037   W (ret);
6038   return ret;
6039 }
6040
6041
6042 /* Note: non-static, called once to set up the initial intfc table */
6043 int
6044 api_sw_interface_dump (vat_main_t * vam)
6045 {
6046   vl_api_sw_interface_dump_t *mp;
6047   vl_api_control_ping_t *mp_ping;
6048   hash_pair_t *p;
6049   name_sort_t *nses = 0, *ns;
6050   sw_interface_subif_t *sub = NULL;
6051   int ret;
6052
6053   /* Toss the old name table */
6054   /* *INDENT-OFF* */
6055   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6056   ({
6057     vec_add2 (nses, ns, 1);
6058     ns->name = (u8 *)(p->key);
6059     ns->value = (u32) p->value[0];
6060   }));
6061   /* *INDENT-ON* */
6062
6063   hash_free (vam->sw_if_index_by_interface_name);
6064
6065   vec_foreach (ns, nses) vec_free (ns->name);
6066
6067   vec_free (nses);
6068
6069   vec_foreach (sub, vam->sw_if_subif_table)
6070   {
6071     vec_free (sub->interface_name);
6072   }
6073   vec_free (vam->sw_if_subif_table);
6074
6075   /* recreate the interface name hash table */
6076   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6077
6078   /* Get list of ethernets */
6079   M (SW_INTERFACE_DUMP, mp);
6080   mp->name_filter_valid = 1;
6081   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6082   S (mp);
6083
6084   /* and local / loopback interfaces */
6085   M (SW_INTERFACE_DUMP, mp);
6086   mp->name_filter_valid = 1;
6087   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6088   S (mp);
6089
6090   /* and packet-generator interfaces */
6091   M (SW_INTERFACE_DUMP, mp);
6092   mp->name_filter_valid = 1;
6093   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6094   S (mp);
6095
6096   /* and vxlan-gpe tunnel interfaces */
6097   M (SW_INTERFACE_DUMP, mp);
6098   mp->name_filter_valid = 1;
6099   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6100            sizeof (mp->name_filter) - 1);
6101   S (mp);
6102
6103   /* and vxlan tunnel interfaces */
6104   M (SW_INTERFACE_DUMP, mp);
6105   mp->name_filter_valid = 1;
6106   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6107   S (mp);
6108
6109   /* and geneve tunnel interfaces */
6110   M (SW_INTERFACE_DUMP, mp);
6111   mp->name_filter_valid = 1;
6112   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6113   S (mp);
6114
6115   /* and host (af_packet) interfaces */
6116   M (SW_INTERFACE_DUMP, mp);
6117   mp->name_filter_valid = 1;
6118   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6119   S (mp);
6120
6121   /* and l2tpv3 tunnel interfaces */
6122   M (SW_INTERFACE_DUMP, mp);
6123   mp->name_filter_valid = 1;
6124   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6125            sizeof (mp->name_filter) - 1);
6126   S (mp);
6127
6128   /* and GRE tunnel interfaces */
6129   M (SW_INTERFACE_DUMP, mp);
6130   mp->name_filter_valid = 1;
6131   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6132   S (mp);
6133
6134   /* and LISP-GPE interfaces */
6135   M (SW_INTERFACE_DUMP, mp);
6136   mp->name_filter_valid = 1;
6137   strncpy ((char *) mp->name_filter, "lisp_gpe",
6138            sizeof (mp->name_filter) - 1);
6139   S (mp);
6140
6141   /* and IPSEC tunnel interfaces */
6142   M (SW_INTERFACE_DUMP, mp);
6143   mp->name_filter_valid = 1;
6144   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6145   S (mp);
6146
6147   /* Use a control ping for synchronization */
6148   MPING (CONTROL_PING, mp_ping);
6149   S (mp_ping);
6150
6151   W (ret);
6152   return ret;
6153 }
6154
6155 static int
6156 api_sw_interface_set_flags (vat_main_t * vam)
6157 {
6158   unformat_input_t *i = vam->input;
6159   vl_api_sw_interface_set_flags_t *mp;
6160   u32 sw_if_index;
6161   u8 sw_if_index_set = 0;
6162   u8 admin_up = 0;
6163   int ret;
6164
6165   /* Parse args required to build the message */
6166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6167     {
6168       if (unformat (i, "admin-up"))
6169         admin_up = 1;
6170       else if (unformat (i, "admin-down"))
6171         admin_up = 0;
6172       else
6173         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6176         sw_if_index_set = 1;
6177       else
6178         break;
6179     }
6180
6181   if (sw_if_index_set == 0)
6182     {
6183       errmsg ("missing interface name or sw_if_index");
6184       return -99;
6185     }
6186
6187   /* Construct the API message */
6188   M (SW_INTERFACE_SET_FLAGS, mp);
6189   mp->sw_if_index = ntohl (sw_if_index);
6190   mp->admin_up_down = admin_up;
6191
6192   /* send it... */
6193   S (mp);
6194
6195   /* Wait for a reply, return the good/bad news... */
6196   W (ret);
6197   return ret;
6198 }
6199
6200 static int
6201 api_sw_interface_clear_stats (vat_main_t * vam)
6202 {
6203   unformat_input_t *i = vam->input;
6204   vl_api_sw_interface_clear_stats_t *mp;
6205   u32 sw_if_index;
6206   u8 sw_if_index_set = 0;
6207   int ret;
6208
6209   /* Parse args required to build the message */
6210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211     {
6212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6213         sw_if_index_set = 1;
6214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6215         sw_if_index_set = 1;
6216       else
6217         break;
6218     }
6219
6220   /* Construct the API message */
6221   M (SW_INTERFACE_CLEAR_STATS, mp);
6222
6223   if (sw_if_index_set == 1)
6224     mp->sw_if_index = ntohl (sw_if_index);
6225   else
6226     mp->sw_if_index = ~0;
6227
6228   /* send it... */
6229   S (mp);
6230
6231   /* Wait for a reply, return the good/bad news... */
6232   W (ret);
6233   return ret;
6234 }
6235
6236 static int
6237 api_sw_interface_add_del_address (vat_main_t * vam)
6238 {
6239   unformat_input_t *i = vam->input;
6240   vl_api_sw_interface_add_del_address_t *mp;
6241   u32 sw_if_index;
6242   u8 sw_if_index_set = 0;
6243   u8 is_add = 1, del_all = 0;
6244   u32 address_length = 0;
6245   u8 v4_address_set = 0;
6246   u8 v6_address_set = 0;
6247   ip4_address_t v4address;
6248   ip6_address_t v6address;
6249   int ret;
6250
6251   /* Parse args required to build the message */
6252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6253     {
6254       if (unformat (i, "del-all"))
6255         del_all = 1;
6256       else if (unformat (i, "del"))
6257         is_add = 0;
6258       else
6259         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6260         sw_if_index_set = 1;
6261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "%U/%d",
6264                          unformat_ip4_address, &v4address, &address_length))
6265         v4_address_set = 1;
6266       else if (unformat (i, "%U/%d",
6267                          unformat_ip6_address, &v6address, &address_length))
6268         v6_address_set = 1;
6269       else
6270         break;
6271     }
6272
6273   if (sw_if_index_set == 0)
6274     {
6275       errmsg ("missing interface name or sw_if_index");
6276       return -99;
6277     }
6278   if (v4_address_set && v6_address_set)
6279     {
6280       errmsg ("both v4 and v6 addresses set");
6281       return -99;
6282     }
6283   if (!v4_address_set && !v6_address_set && !del_all)
6284     {
6285       errmsg ("no addresses set");
6286       return -99;
6287     }
6288
6289   /* Construct the API message */
6290   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6291
6292   mp->sw_if_index = ntohl (sw_if_index);
6293   mp->is_add = is_add;
6294   mp->del_all = del_all;
6295   if (v6_address_set)
6296     {
6297       mp->is_ipv6 = 1;
6298       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6299     }
6300   else
6301     {
6302       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6303     }
6304   mp->address_length = address_length;
6305
6306   /* send it... */
6307   S (mp);
6308
6309   /* Wait for a reply, return good/bad news  */
6310   W (ret);
6311   return ret;
6312 }
6313
6314 static int
6315 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6316 {
6317   unformat_input_t *i = vam->input;
6318   vl_api_sw_interface_set_mpls_enable_t *mp;
6319   u32 sw_if_index;
6320   u8 sw_if_index_set = 0;
6321   u8 enable = 1;
6322   int ret;
6323
6324   /* Parse args required to build the message */
6325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6326     {
6327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6328         sw_if_index_set = 1;
6329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         sw_if_index_set = 1;
6331       else if (unformat (i, "disable"))
6332         enable = 0;
6333       else if (unformat (i, "dis"))
6334         enable = 0;
6335       else
6336         break;
6337     }
6338
6339   if (sw_if_index_set == 0)
6340     {
6341       errmsg ("missing interface name or sw_if_index");
6342       return -99;
6343     }
6344
6345   /* Construct the API message */
6346   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6347
6348   mp->sw_if_index = ntohl (sw_if_index);
6349   mp->enable = enable;
6350
6351   /* send it... */
6352   S (mp);
6353
6354   /* Wait for a reply... */
6355   W (ret);
6356   return ret;
6357 }
6358
6359 static int
6360 api_sw_interface_set_table (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_sw_interface_set_table_t *mp;
6364   u32 sw_if_index, vrf_id = 0;
6365   u8 sw_if_index_set = 0;
6366   u8 is_ipv6 = 0;
6367   int ret;
6368
6369   /* Parse args required to build the message */
6370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6371     {
6372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6373         sw_if_index_set = 1;
6374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6375         sw_if_index_set = 1;
6376       else if (unformat (i, "vrf %d", &vrf_id))
6377         ;
6378       else if (unformat (i, "ipv6"))
6379         is_ipv6 = 1;
6380       else
6381         break;
6382     }
6383
6384   if (sw_if_index_set == 0)
6385     {
6386       errmsg ("missing interface name or sw_if_index");
6387       return -99;
6388     }
6389
6390   /* Construct the API message */
6391   M (SW_INTERFACE_SET_TABLE, mp);
6392
6393   mp->sw_if_index = ntohl (sw_if_index);
6394   mp->is_ipv6 = is_ipv6;
6395   mp->vrf_id = ntohl (vrf_id);
6396
6397   /* send it... */
6398   S (mp);
6399
6400   /* Wait for a reply... */
6401   W (ret);
6402   return ret;
6403 }
6404
6405 static void vl_api_sw_interface_get_table_reply_t_handler
6406   (vl_api_sw_interface_get_table_reply_t * mp)
6407 {
6408   vat_main_t *vam = &vat_main;
6409
6410   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6411
6412   vam->retval = ntohl (mp->retval);
6413   vam->result_ready = 1;
6414
6415 }
6416
6417 static void vl_api_sw_interface_get_table_reply_t_handler_json
6418   (vl_api_sw_interface_get_table_reply_t * mp)
6419 {
6420   vat_main_t *vam = &vat_main;
6421   vat_json_node_t node;
6422
6423   vat_json_init_object (&node);
6424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6425   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6426
6427   vat_json_print (vam->ofp, &node);
6428   vat_json_free (&node);
6429
6430   vam->retval = ntohl (mp->retval);
6431   vam->result_ready = 1;
6432 }
6433
6434 static int
6435 api_sw_interface_get_table (vat_main_t * vam)
6436 {
6437   unformat_input_t *i = vam->input;
6438   vl_api_sw_interface_get_table_t *mp;
6439   u32 sw_if_index;
6440   u8 sw_if_index_set = 0;
6441   u8 is_ipv6 = 0;
6442   int ret;
6443
6444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6445     {
6446       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6447         sw_if_index_set = 1;
6448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6449         sw_if_index_set = 1;
6450       else if (unformat (i, "ipv6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   M (SW_INTERFACE_GET_TABLE, mp);
6463   mp->sw_if_index = htonl (sw_if_index);
6464   mp->is_ipv6 = is_ipv6;
6465
6466   S (mp);
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_vpath (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_vpath_t *mp;
6476   u32 sw_if_index = 0;
6477   u8 sw_if_index_set = 0;
6478   u8 is_enable = 0;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "enable"))
6489         is_enable = 1;
6490       else if (unformat (i, "disable"))
6491         is_enable = 0;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index_set == 0)
6497     {
6498       errmsg ("missing interface name or sw_if_index");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (SW_INTERFACE_SET_VPATH, mp);
6504
6505   mp->sw_if_index = ntohl (sw_if_index);
6506   mp->enable = is_enable;
6507
6508   /* send it... */
6509   S (mp);
6510
6511   /* Wait for a reply... */
6512   W (ret);
6513   return ret;
6514 }
6515
6516 static int
6517 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6518 {
6519   unformat_input_t *i = vam->input;
6520   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6521   u32 sw_if_index = 0;
6522   u8 sw_if_index_set = 0;
6523   u8 is_enable = 1;
6524   u8 is_ipv6 = 0;
6525   int ret;
6526
6527   /* Parse args required to build the message */
6528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6529     {
6530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6531         sw_if_index_set = 1;
6532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6533         sw_if_index_set = 1;
6534       else if (unformat (i, "enable"))
6535         is_enable = 1;
6536       else if (unformat (i, "disable"))
6537         is_enable = 0;
6538       else if (unformat (i, "ip4"))
6539         is_ipv6 = 0;
6540       else if (unformat (i, "ip6"))
6541         is_ipv6 = 1;
6542       else
6543         break;
6544     }
6545
6546   if (sw_if_index_set == 0)
6547     {
6548       errmsg ("missing interface name or sw_if_index");
6549       return -99;
6550     }
6551
6552   /* Construct the API message */
6553   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6554
6555   mp->sw_if_index = ntohl (sw_if_index);
6556   mp->enable = is_enable;
6557   mp->is_ipv6 = is_ipv6;
6558
6559   /* send it... */
6560   S (mp);
6561
6562   /* Wait for a reply... */
6563   W (ret);
6564   return ret;
6565 }
6566
6567 static int
6568 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6569 {
6570   unformat_input_t *i = vam->input;
6571   vl_api_sw_interface_set_geneve_bypass_t *mp;
6572   u32 sw_if_index = 0;
6573   u8 sw_if_index_set = 0;
6574   u8 is_enable = 1;
6575   u8 is_ipv6 = 0;
6576   int ret;
6577
6578   /* Parse args required to build the message */
6579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580     {
6581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "enable"))
6586         is_enable = 1;
6587       else if (unformat (i, "disable"))
6588         is_enable = 0;
6589       else if (unformat (i, "ip4"))
6590         is_ipv6 = 0;
6591       else if (unformat (i, "ip6"))
6592         is_ipv6 = 1;
6593       else
6594         break;
6595     }
6596
6597   if (sw_if_index_set == 0)
6598     {
6599       errmsg ("missing interface name or sw_if_index");
6600       return -99;
6601     }
6602
6603   /* Construct the API message */
6604   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6605
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->enable = is_enable;
6608   mp->is_ipv6 = is_ipv6;
6609
6610   /* send it... */
6611   S (mp);
6612
6613   /* Wait for a reply... */
6614   W (ret);
6615   return ret;
6616 }
6617
6618 static int
6619 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_sw_interface_set_l2_xconnect_t *mp;
6623   u32 rx_sw_if_index;
6624   u8 rx_sw_if_index_set = 0;
6625   u32 tx_sw_if_index;
6626   u8 tx_sw_if_index_set = 0;
6627   u8 enable = 1;
6628   int ret;
6629
6630   /* Parse args required to build the message */
6631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6632     {
6633       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6634         rx_sw_if_index_set = 1;
6635       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6636         tx_sw_if_index_set = 1;
6637       else if (unformat (i, "rx"))
6638         {
6639           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640             {
6641               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6642                             &rx_sw_if_index))
6643                 rx_sw_if_index_set = 1;
6644             }
6645           else
6646             break;
6647         }
6648       else if (unformat (i, "tx"))
6649         {
6650           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651             {
6652               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6653                             &tx_sw_if_index))
6654                 tx_sw_if_index_set = 1;
6655             }
6656           else
6657             break;
6658         }
6659       else if (unformat (i, "enable"))
6660         enable = 1;
6661       else if (unformat (i, "disable"))
6662         enable = 0;
6663       else
6664         break;
6665     }
6666
6667   if (rx_sw_if_index_set == 0)
6668     {
6669       errmsg ("missing rx interface name or rx_sw_if_index");
6670       return -99;
6671     }
6672
6673   if (enable && (tx_sw_if_index_set == 0))
6674     {
6675       errmsg ("missing tx interface name or tx_sw_if_index");
6676       return -99;
6677     }
6678
6679   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6680
6681   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6682   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6683   mp->enable = enable;
6684
6685   S (mp);
6686   W (ret);
6687   return ret;
6688 }
6689
6690 static int
6691 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_sw_interface_set_l2_bridge_t *mp;
6695   u32 rx_sw_if_index;
6696   u8 rx_sw_if_index_set = 0;
6697   u32 bd_id;
6698   u8 bd_id_set = 0;
6699   u8 bvi = 0;
6700   u32 shg = 0;
6701   u8 enable = 1;
6702   int ret;
6703
6704   /* Parse args required to build the message */
6705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6706     {
6707       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6708         rx_sw_if_index_set = 1;
6709       else if (unformat (i, "bd_id %d", &bd_id))
6710         bd_id_set = 1;
6711       else
6712         if (unformat
6713             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6714         rx_sw_if_index_set = 1;
6715       else if (unformat (i, "shg %d", &shg))
6716         ;
6717       else if (unformat (i, "bvi"))
6718         bvi = 1;
6719       else if (unformat (i, "enable"))
6720         enable = 1;
6721       else if (unformat (i, "disable"))
6722         enable = 0;
6723       else
6724         break;
6725     }
6726
6727   if (rx_sw_if_index_set == 0)
6728     {
6729       errmsg ("missing rx interface name or sw_if_index");
6730       return -99;
6731     }
6732
6733   if (enable && (bd_id_set == 0))
6734     {
6735       errmsg ("missing bridge domain");
6736       return -99;
6737     }
6738
6739   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6740
6741   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6742   mp->bd_id = ntohl (bd_id);
6743   mp->shg = (u8) shg;
6744   mp->bvi = bvi;
6745   mp->enable = enable;
6746
6747   S (mp);
6748   W (ret);
6749   return ret;
6750 }
6751
6752 static int
6753 api_bridge_domain_dump (vat_main_t * vam)
6754 {
6755   unformat_input_t *i = vam->input;
6756   vl_api_bridge_domain_dump_t *mp;
6757   vl_api_control_ping_t *mp_ping;
6758   u32 bd_id = ~0;
6759   int ret;
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "bd_id %d", &bd_id))
6765         ;
6766       else
6767         break;
6768     }
6769
6770   M (BRIDGE_DOMAIN_DUMP, mp);
6771   mp->bd_id = ntohl (bd_id);
6772   S (mp);
6773
6774   /* Use a control ping for synchronization */
6775   MPING (CONTROL_PING, mp_ping);
6776   S (mp_ping);
6777
6778   W (ret);
6779   return ret;
6780 }
6781
6782 static int
6783 api_bridge_domain_add_del (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_bridge_domain_add_del_t *mp;
6787   u32 bd_id = ~0;
6788   u8 is_add = 1;
6789   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6790   u8 *bd_tag = NULL;
6791   u32 mac_age = 0;
6792   int ret;
6793
6794   /* Parse args required to build the message */
6795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6796     {
6797       if (unformat (i, "bd_id %d", &bd_id))
6798         ;
6799       else if (unformat (i, "flood %d", &flood))
6800         ;
6801       else if (unformat (i, "uu-flood %d", &uu_flood))
6802         ;
6803       else if (unformat (i, "forward %d", &forward))
6804         ;
6805       else if (unformat (i, "learn %d", &learn))
6806         ;
6807       else if (unformat (i, "arp-term %d", &arp_term))
6808         ;
6809       else if (unformat (i, "mac-age %d", &mac_age))
6810         ;
6811       else if (unformat (i, "bd-tag %s", &bd_tag))
6812         ;
6813       else if (unformat (i, "del"))
6814         {
6815           is_add = 0;
6816           flood = uu_flood = forward = learn = 0;
6817         }
6818       else
6819         break;
6820     }
6821
6822   if (bd_id == ~0)
6823     {
6824       errmsg ("missing bridge domain");
6825       ret = -99;
6826       goto done;
6827     }
6828
6829   if (mac_age > 255)
6830     {
6831       errmsg ("mac age must be less than 256 ");
6832       ret = -99;
6833       goto done;
6834     }
6835
6836   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6837     {
6838       errmsg ("bd-tag cannot be longer than 63");
6839       ret = -99;
6840       goto done;
6841     }
6842
6843   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6844
6845   mp->bd_id = ntohl (bd_id);
6846   mp->flood = flood;
6847   mp->uu_flood = uu_flood;
6848   mp->forward = forward;
6849   mp->learn = learn;
6850   mp->arp_term = arp_term;
6851   mp->is_add = is_add;
6852   mp->mac_age = (u8) mac_age;
6853   if (bd_tag)
6854     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6855
6856   S (mp);
6857   W (ret);
6858
6859 done:
6860   vec_free (bd_tag);
6861   return ret;
6862 }
6863
6864 static int
6865 api_l2fib_flush_bd (vat_main_t * vam)
6866 {
6867   unformat_input_t *i = vam->input;
6868   vl_api_l2fib_flush_bd_t *mp;
6869   u32 bd_id = ~0;
6870   int ret;
6871
6872   /* Parse args required to build the message */
6873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6874     {
6875       if (unformat (i, "bd_id %d", &bd_id));
6876       else
6877         break;
6878     }
6879
6880   if (bd_id == ~0)
6881     {
6882       errmsg ("missing bridge domain");
6883       return -99;
6884     }
6885
6886   M (L2FIB_FLUSH_BD, mp);
6887
6888   mp->bd_id = htonl (bd_id);
6889
6890   S (mp);
6891   W (ret);
6892   return ret;
6893 }
6894
6895 static int
6896 api_l2fib_flush_int (vat_main_t * vam)
6897 {
6898   unformat_input_t *i = vam->input;
6899   vl_api_l2fib_flush_int_t *mp;
6900   u32 sw_if_index = ~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, "sw_if_index %d", &sw_if_index));
6907       else
6908         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6909       else
6910         break;
6911     }
6912
6913   if (sw_if_index == ~0)
6914     {
6915       errmsg ("missing interface name or sw_if_index");
6916       return -99;
6917     }
6918
6919   M (L2FIB_FLUSH_INT, mp);
6920
6921   mp->sw_if_index = ntohl (sw_if_index);
6922
6923   S (mp);
6924   W (ret);
6925   return ret;
6926 }
6927
6928 static int
6929 api_l2fib_add_del (vat_main_t * vam)
6930 {
6931   unformat_input_t *i = vam->input;
6932   vl_api_l2fib_add_del_t *mp;
6933   f64 timeout;
6934   u64 mac = 0;
6935   u8 mac_set = 0;
6936   u32 bd_id;
6937   u8 bd_id_set = 0;
6938   u32 sw_if_index = ~0;
6939   u8 sw_if_index_set = 0;
6940   u8 is_add = 1;
6941   u8 static_mac = 0;
6942   u8 filter_mac = 0;
6943   u8 bvi_mac = 0;
6944   int count = 1;
6945   f64 before = 0;
6946   int j;
6947
6948   /* Parse args required to build the message */
6949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950     {
6951       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6952         mac_set = 1;
6953       else if (unformat (i, "bd_id %d", &bd_id))
6954         bd_id_set = 1;
6955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6956         sw_if_index_set = 1;
6957       else if (unformat (i, "sw_if"))
6958         {
6959           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960             {
6961               if (unformat
6962                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6963                 sw_if_index_set = 1;
6964             }
6965           else
6966             break;
6967         }
6968       else if (unformat (i, "static"))
6969         static_mac = 1;
6970       else if (unformat (i, "filter"))
6971         {
6972           filter_mac = 1;
6973           static_mac = 1;
6974         }
6975       else if (unformat (i, "bvi"))
6976         {
6977           bvi_mac = 1;
6978           static_mac = 1;
6979         }
6980       else if (unformat (i, "del"))
6981         is_add = 0;
6982       else if (unformat (i, "count %d", &count))
6983         ;
6984       else
6985         break;
6986     }
6987
6988   if (mac_set == 0)
6989     {
6990       errmsg ("missing mac address");
6991       return -99;
6992     }
6993
6994   if (bd_id_set == 0)
6995     {
6996       errmsg ("missing bridge domain");
6997       return -99;
6998     }
6999
7000   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7001     {
7002       errmsg ("missing interface name or sw_if_index");
7003       return -99;
7004     }
7005
7006   if (count > 1)
7007     {
7008       /* Turn on async mode */
7009       vam->async_mode = 1;
7010       vam->async_errors = 0;
7011       before = vat_time_now (vam);
7012     }
7013
7014   for (j = 0; j < count; j++)
7015     {
7016       M (L2FIB_ADD_DEL, mp);
7017
7018       mp->mac = mac;
7019       mp->bd_id = ntohl (bd_id);
7020       mp->is_add = is_add;
7021
7022       if (is_add)
7023         {
7024           mp->sw_if_index = ntohl (sw_if_index);
7025           mp->static_mac = static_mac;
7026           mp->filter_mac = filter_mac;
7027           mp->bvi_mac = bvi_mac;
7028         }
7029       increment_mac_address (&mac);
7030       /* send it... */
7031       S (mp);
7032     }
7033
7034   if (count > 1)
7035     {
7036       vl_api_control_ping_t *mp_ping;
7037       f64 after;
7038
7039       /* Shut off async mode */
7040       vam->async_mode = 0;
7041
7042       MPING (CONTROL_PING, mp_ping);
7043       S (mp_ping);
7044
7045       timeout = vat_time_now (vam) + 1.0;
7046       while (vat_time_now (vam) < timeout)
7047         if (vam->result_ready == 1)
7048           goto out;
7049       vam->retval = -99;
7050
7051     out:
7052       if (vam->retval == -99)
7053         errmsg ("timeout");
7054
7055       if (vam->async_errors > 0)
7056         {
7057           errmsg ("%d asynchronous errors", vam->async_errors);
7058           vam->retval = -98;
7059         }
7060       vam->async_errors = 0;
7061       after = vat_time_now (vam);
7062
7063       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7064              count, after - before, count / (after - before));
7065     }
7066   else
7067     {
7068       int ret;
7069
7070       /* Wait for a reply... */
7071       W (ret);
7072       return ret;
7073     }
7074   /* Return the good/bad news */
7075   return (vam->retval);
7076 }
7077
7078 static int
7079 api_bridge_domain_set_mac_age (vat_main_t * vam)
7080 {
7081   unformat_input_t *i = vam->input;
7082   vl_api_bridge_domain_set_mac_age_t *mp;
7083   u32 bd_id = ~0;
7084   u32 mac_age = 0;
7085   int ret;
7086
7087   /* Parse args required to build the message */
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "bd_id %d", &bd_id));
7091       else if (unformat (i, "mac-age %d", &mac_age));
7092       else
7093         break;
7094     }
7095
7096   if (bd_id == ~0)
7097     {
7098       errmsg ("missing bridge domain");
7099       return -99;
7100     }
7101
7102   if (mac_age > 255)
7103     {
7104       errmsg ("mac age must be less than 256 ");
7105       return -99;
7106     }
7107
7108   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7109
7110   mp->bd_id = htonl (bd_id);
7111   mp->mac_age = (u8) mac_age;
7112
7113   S (mp);
7114   W (ret);
7115   return ret;
7116 }
7117
7118 static int
7119 api_l2_flags (vat_main_t * vam)
7120 {
7121   unformat_input_t *i = vam->input;
7122   vl_api_l2_flags_t *mp;
7123   u32 sw_if_index;
7124   u32 flags = 0;
7125   u8 sw_if_index_set = 0;
7126   u8 is_set = 0;
7127   int ret;
7128
7129   /* Parse args required to build the message */
7130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131     {
7132       if (unformat (i, "sw_if_index %d", &sw_if_index))
7133         sw_if_index_set = 1;
7134       else if (unformat (i, "sw_if"))
7135         {
7136           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137             {
7138               if (unformat
7139                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7140                 sw_if_index_set = 1;
7141             }
7142           else
7143             break;
7144         }
7145       else if (unformat (i, "learn"))
7146         flags |= L2_LEARN;
7147       else if (unformat (i, "forward"))
7148         flags |= L2_FWD;
7149       else if (unformat (i, "flood"))
7150         flags |= L2_FLOOD;
7151       else if (unformat (i, "uu-flood"))
7152         flags |= L2_UU_FLOOD;
7153       else if (unformat (i, "arp-term"))
7154         flags |= L2_ARP_TERM;
7155       else if (unformat (i, "off"))
7156         is_set = 0;
7157       else if (unformat (i, "disable"))
7158         is_set = 0;
7159       else
7160         break;
7161     }
7162
7163   if (sw_if_index_set == 0)
7164     {
7165       errmsg ("missing interface name or sw_if_index");
7166       return -99;
7167     }
7168
7169   M (L2_FLAGS, mp);
7170
7171   mp->sw_if_index = ntohl (sw_if_index);
7172   mp->feature_bitmap = ntohl (flags);
7173   mp->is_set = is_set;
7174
7175   S (mp);
7176   W (ret);
7177   return ret;
7178 }
7179
7180 static int
7181 api_bridge_flags (vat_main_t * vam)
7182 {
7183   unformat_input_t *i = vam->input;
7184   vl_api_bridge_flags_t *mp;
7185   u32 bd_id;
7186   u8 bd_id_set = 0;
7187   u8 is_set = 1;
7188   u32 flags = 0;
7189   int ret;
7190
7191   /* Parse args required to build the message */
7192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7193     {
7194       if (unformat (i, "bd_id %d", &bd_id))
7195         bd_id_set = 1;
7196       else if (unformat (i, "learn"))
7197         flags |= L2_LEARN;
7198       else if (unformat (i, "forward"))
7199         flags |= L2_FWD;
7200       else if (unformat (i, "flood"))
7201         flags |= L2_FLOOD;
7202       else if (unformat (i, "uu-flood"))
7203         flags |= L2_UU_FLOOD;
7204       else if (unformat (i, "arp-term"))
7205         flags |= L2_ARP_TERM;
7206       else if (unformat (i, "off"))
7207         is_set = 0;
7208       else if (unformat (i, "disable"))
7209         is_set = 0;
7210       else
7211         break;
7212     }
7213
7214   if (bd_id_set == 0)
7215     {
7216       errmsg ("missing bridge domain");
7217       return -99;
7218     }
7219
7220   M (BRIDGE_FLAGS, mp);
7221
7222   mp->bd_id = ntohl (bd_id);
7223   mp->feature_bitmap = ntohl (flags);
7224   mp->is_set = is_set;
7225
7226   S (mp);
7227   W (ret);
7228   return ret;
7229 }
7230
7231 static int
7232 api_bd_ip_mac_add_del (vat_main_t * vam)
7233 {
7234   unformat_input_t *i = vam->input;
7235   vl_api_bd_ip_mac_add_del_t *mp;
7236   u32 bd_id;
7237   u8 is_ipv6 = 0;
7238   u8 is_add = 1;
7239   u8 bd_id_set = 0;
7240   u8 ip_set = 0;
7241   u8 mac_set = 0;
7242   ip4_address_t v4addr;
7243   ip6_address_t v6addr;
7244   u8 macaddr[6];
7245   int ret;
7246
7247
7248   /* Parse args required to build the message */
7249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7250     {
7251       if (unformat (i, "bd_id %d", &bd_id))
7252         {
7253           bd_id_set++;
7254         }
7255       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7256         {
7257           ip_set++;
7258         }
7259       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7260         {
7261           ip_set++;
7262           is_ipv6++;
7263         }
7264       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7265         {
7266           mac_set++;
7267         }
7268       else if (unformat (i, "del"))
7269         is_add = 0;
7270       else
7271         break;
7272     }
7273
7274   if (bd_id_set == 0)
7275     {
7276       errmsg ("missing bridge domain");
7277       return -99;
7278     }
7279   else if (ip_set == 0)
7280     {
7281       errmsg ("missing IP address");
7282       return -99;
7283     }
7284   else if (mac_set == 0)
7285     {
7286       errmsg ("missing MAC address");
7287       return -99;
7288     }
7289
7290   M (BD_IP_MAC_ADD_DEL, mp);
7291
7292   mp->bd_id = ntohl (bd_id);
7293   mp->is_ipv6 = is_ipv6;
7294   mp->is_add = is_add;
7295   if (is_ipv6)
7296     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7297   else
7298     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7299   clib_memcpy (mp->mac_address, macaddr, 6);
7300   S (mp);
7301   W (ret);
7302   return ret;
7303 }
7304
7305 static int
7306 api_tap_connect (vat_main_t * vam)
7307 {
7308   unformat_input_t *i = vam->input;
7309   vl_api_tap_connect_t *mp;
7310   u8 mac_address[6];
7311   u8 random_mac = 1;
7312   u8 name_set = 0;
7313   u8 *tap_name;
7314   u8 *tag = 0;
7315   ip4_address_t ip4_address;
7316   u32 ip4_mask_width;
7317   int ip4_address_set = 0;
7318   ip6_address_t ip6_address;
7319   u32 ip6_mask_width;
7320   int ip6_address_set = 0;
7321   int ret;
7322
7323   memset (mac_address, 0, sizeof (mac_address));
7324
7325   /* Parse args required to build the message */
7326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7327     {
7328       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7329         {
7330           random_mac = 0;
7331         }
7332       else if (unformat (i, "random-mac"))
7333         random_mac = 1;
7334       else if (unformat (i, "tapname %s", &tap_name))
7335         name_set = 1;
7336       else if (unformat (i, "tag %s", &tag))
7337         ;
7338       else if (unformat (i, "address %U/%d",
7339                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7340         ip4_address_set = 1;
7341       else if (unformat (i, "address %U/%d",
7342                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7343         ip6_address_set = 1;
7344       else
7345         break;
7346     }
7347
7348   if (name_set == 0)
7349     {
7350       errmsg ("missing tap name");
7351       return -99;
7352     }
7353   if (vec_len (tap_name) > 63)
7354     {
7355       errmsg ("tap name too long");
7356       return -99;
7357     }
7358   vec_add1 (tap_name, 0);
7359
7360   if (vec_len (tag) > 63)
7361     {
7362       errmsg ("tag too long");
7363       return -99;
7364     }
7365
7366   /* Construct the API message */
7367   M (TAP_CONNECT, mp);
7368
7369   mp->use_random_mac = random_mac;
7370   clib_memcpy (mp->mac_address, mac_address, 6);
7371   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7372   if (tag)
7373     clib_memcpy (mp->tag, tag, vec_len (tag));
7374
7375   if (ip4_address_set)
7376     {
7377       mp->ip4_address_set = 1;
7378       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7379       mp->ip4_mask_width = ip4_mask_width;
7380     }
7381   if (ip6_address_set)
7382     {
7383       mp->ip6_address_set = 1;
7384       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7385       mp->ip6_mask_width = ip6_mask_width;
7386     }
7387
7388   vec_free (tap_name);
7389   vec_free (tag);
7390
7391   /* send it... */
7392   S (mp);
7393
7394   /* Wait for a reply... */
7395   W (ret);
7396   return ret;
7397 }
7398
7399 static int
7400 api_tap_modify (vat_main_t * vam)
7401 {
7402   unformat_input_t *i = vam->input;
7403   vl_api_tap_modify_t *mp;
7404   u8 mac_address[6];
7405   u8 random_mac = 1;
7406   u8 name_set = 0;
7407   u8 *tap_name;
7408   u32 sw_if_index = ~0;
7409   u8 sw_if_index_set = 0;
7410   int ret;
7411
7412   memset (mac_address, 0, sizeof (mac_address));
7413
7414   /* Parse args required to build the message */
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7418         sw_if_index_set = 1;
7419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7420         sw_if_index_set = 1;
7421       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7422         {
7423           random_mac = 0;
7424         }
7425       else if (unformat (i, "random-mac"))
7426         random_mac = 1;
7427       else if (unformat (i, "tapname %s", &tap_name))
7428         name_set = 1;
7429       else
7430         break;
7431     }
7432
7433   if (sw_if_index_set == 0)
7434     {
7435       errmsg ("missing vpp interface name");
7436       return -99;
7437     }
7438   if (name_set == 0)
7439     {
7440       errmsg ("missing tap name");
7441       return -99;
7442     }
7443   if (vec_len (tap_name) > 63)
7444     {
7445       errmsg ("tap name too long");
7446     }
7447   vec_add1 (tap_name, 0);
7448
7449   /* Construct the API message */
7450   M (TAP_MODIFY, mp);
7451
7452   mp->use_random_mac = random_mac;
7453   mp->sw_if_index = ntohl (sw_if_index);
7454   clib_memcpy (mp->mac_address, mac_address, 6);
7455   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7456   vec_free (tap_name);
7457
7458   /* send it... */
7459   S (mp);
7460
7461   /* Wait for a reply... */
7462   W (ret);
7463   return ret;
7464 }
7465
7466 static int
7467 api_tap_delete (vat_main_t * vam)
7468 {
7469   unformat_input_t *i = vam->input;
7470   vl_api_tap_delete_t *mp;
7471   u32 sw_if_index = ~0;
7472   u8 sw_if_index_set = 0;
7473   int ret;
7474
7475   /* Parse args required to build the message */
7476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7477     {
7478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7479         sw_if_index_set = 1;
7480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7481         sw_if_index_set = 1;
7482       else
7483         break;
7484     }
7485
7486   if (sw_if_index_set == 0)
7487     {
7488       errmsg ("missing vpp interface name");
7489       return -99;
7490     }
7491
7492   /* Construct the API message */
7493   M (TAP_DELETE, mp);
7494
7495   mp->sw_if_index = ntohl (sw_if_index);
7496
7497   /* send it... */
7498   S (mp);
7499
7500   /* Wait for a reply... */
7501   W (ret);
7502   return ret;
7503 }
7504
7505 static int
7506 api_ip_table_add_del (vat_main_t * vam)
7507 {
7508   unformat_input_t *i = vam->input;
7509   vl_api_ip_table_add_del_t *mp;
7510   u32 table_id = ~0;
7511   u8 is_ipv6 = 0;
7512   u8 is_add = 1;
7513   int ret = 0;
7514
7515   /* Parse args required to build the message */
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "ipv6"))
7519         is_ipv6 = 1;
7520       else if (unformat (i, "del"))
7521         is_add = 0;
7522       else if (unformat (i, "add"))
7523         is_add = 1;
7524       else if (unformat (i, "table %d", &table_id))
7525         ;
7526       else
7527         {
7528           clib_warning ("parse error '%U'", format_unformat_error, i);
7529           return -99;
7530         }
7531     }
7532
7533   if (~0 == table_id)
7534     {
7535       errmsg ("missing table-ID");
7536       return -99;
7537     }
7538
7539   /* Construct the API message */
7540   M (IP_TABLE_ADD_DEL, mp);
7541
7542   mp->table_id = ntohl (table_id);
7543   mp->is_ipv6 = is_ipv6;
7544   mp->is_add = is_add;
7545
7546   /* send it... */
7547   S (mp);
7548
7549   /* Wait for a reply... */
7550   W (ret);
7551
7552   return ret;
7553 }
7554
7555 static int
7556 api_ip_add_del_route (vat_main_t * vam)
7557 {
7558   unformat_input_t *i = vam->input;
7559   vl_api_ip_add_del_route_t *mp;
7560   u32 sw_if_index = ~0, vrf_id = 0;
7561   u8 is_ipv6 = 0;
7562   u8 is_local = 0, is_drop = 0;
7563   u8 is_unreach = 0, is_prohibit = 0;
7564   u8 create_vrf_if_needed = 0;
7565   u8 is_add = 1;
7566   u32 next_hop_weight = 1;
7567   u8 is_multipath = 0;
7568   u8 address_set = 0;
7569   u8 address_length_set = 0;
7570   u32 next_hop_table_id = 0;
7571   u32 resolve_attempts = 0;
7572   u32 dst_address_length = 0;
7573   u8 next_hop_set = 0;
7574   ip4_address_t v4_dst_address, v4_next_hop_address;
7575   ip6_address_t v6_dst_address, v6_next_hop_address;
7576   int count = 1;
7577   int j;
7578   f64 before = 0;
7579   u32 random_add_del = 0;
7580   u32 *random_vector = 0;
7581   uword *random_hash;
7582   u32 random_seed = 0xdeaddabe;
7583   u32 classify_table_index = ~0;
7584   u8 is_classify = 0;
7585   u8 resolve_host = 0, resolve_attached = 0;
7586   mpls_label_t *next_hop_out_label_stack = NULL;
7587   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7588   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7589
7590   /* Parse args required to build the message */
7591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7592     {
7593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7594         ;
7595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7596         ;
7597       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7598         {
7599           address_set = 1;
7600           is_ipv6 = 0;
7601         }
7602       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7603         {
7604           address_set = 1;
7605           is_ipv6 = 1;
7606         }
7607       else if (unformat (i, "/%d", &dst_address_length))
7608         {
7609           address_length_set = 1;
7610         }
7611
7612       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7613                                          &v4_next_hop_address))
7614         {
7615           next_hop_set = 1;
7616         }
7617       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7618                                          &v6_next_hop_address))
7619         {
7620           next_hop_set = 1;
7621         }
7622       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7623         ;
7624       else if (unformat (i, "weight %d", &next_hop_weight))
7625         ;
7626       else if (unformat (i, "drop"))
7627         {
7628           is_drop = 1;
7629         }
7630       else if (unformat (i, "null-send-unreach"))
7631         {
7632           is_unreach = 1;
7633         }
7634       else if (unformat (i, "null-send-prohibit"))
7635         {
7636           is_prohibit = 1;
7637         }
7638       else if (unformat (i, "local"))
7639         {
7640           is_local = 1;
7641         }
7642       else if (unformat (i, "classify %d", &classify_table_index))
7643         {
7644           is_classify = 1;
7645         }
7646       else if (unformat (i, "del"))
7647         is_add = 0;
7648       else if (unformat (i, "add"))
7649         is_add = 1;
7650       else if (unformat (i, "resolve-via-host"))
7651         resolve_host = 1;
7652       else if (unformat (i, "resolve-via-attached"))
7653         resolve_attached = 1;
7654       else if (unformat (i, "multipath"))
7655         is_multipath = 1;
7656       else if (unformat (i, "vrf %d", &vrf_id))
7657         ;
7658       else if (unformat (i, "create-vrf"))
7659         create_vrf_if_needed = 1;
7660       else if (unformat (i, "count %d", &count))
7661         ;
7662       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7663         ;
7664       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7665         ;
7666       else if (unformat (i, "out-label %d", &next_hop_out_label))
7667         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7668       else if (unformat (i, "via-label %d", &next_hop_via_label))
7669         ;
7670       else if (unformat (i, "random"))
7671         random_add_del = 1;
7672       else if (unformat (i, "seed %d", &random_seed))
7673         ;
7674       else
7675         {
7676           clib_warning ("parse error '%U'", format_unformat_error, i);
7677           return -99;
7678         }
7679     }
7680
7681   if (!next_hop_set && !is_drop && !is_local &&
7682       !is_classify && !is_unreach && !is_prohibit &&
7683       MPLS_LABEL_INVALID == next_hop_via_label)
7684     {
7685       errmsg
7686         ("next hop / local / drop / unreach / prohibit / classify not set");
7687       return -99;
7688     }
7689
7690   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7691     {
7692       errmsg ("next hop and next-hop via label set");
7693       return -99;
7694     }
7695   if (address_set == 0)
7696     {
7697       errmsg ("missing addresses");
7698       return -99;
7699     }
7700
7701   if (address_length_set == 0)
7702     {
7703       errmsg ("missing address length");
7704       return -99;
7705     }
7706
7707   /* Generate a pile of unique, random routes */
7708   if (random_add_del)
7709     {
7710       u32 this_random_address;
7711       random_hash = hash_create (count, sizeof (uword));
7712
7713       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7714       for (j = 0; j <= count; j++)
7715         {
7716           do
7717             {
7718               this_random_address = random_u32 (&random_seed);
7719               this_random_address =
7720                 clib_host_to_net_u32 (this_random_address);
7721             }
7722           while (hash_get (random_hash, this_random_address));
7723           vec_add1 (random_vector, this_random_address);
7724           hash_set (random_hash, this_random_address, 1);
7725         }
7726       hash_free (random_hash);
7727       v4_dst_address.as_u32 = random_vector[0];
7728     }
7729
7730   if (count > 1)
7731     {
7732       /* Turn on async mode */
7733       vam->async_mode = 1;
7734       vam->async_errors = 0;
7735       before = vat_time_now (vam);
7736     }
7737
7738   for (j = 0; j < count; j++)
7739     {
7740       /* Construct the API message */
7741       M2 (IP_ADD_DEL_ROUTE, mp,
7742           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7743
7744       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7745       mp->table_id = ntohl (vrf_id);
7746       mp->create_vrf_if_needed = create_vrf_if_needed;
7747
7748       mp->is_add = is_add;
7749       mp->is_drop = is_drop;
7750       mp->is_unreach = is_unreach;
7751       mp->is_prohibit = is_prohibit;
7752       mp->is_ipv6 = is_ipv6;
7753       mp->is_local = is_local;
7754       mp->is_classify = is_classify;
7755       mp->is_multipath = is_multipath;
7756       mp->is_resolve_host = resolve_host;
7757       mp->is_resolve_attached = resolve_attached;
7758       mp->next_hop_weight = next_hop_weight;
7759       mp->dst_address_length = dst_address_length;
7760       mp->next_hop_table_id = ntohl (next_hop_table_id);
7761       mp->classify_table_index = ntohl (classify_table_index);
7762       mp->next_hop_via_label = ntohl (next_hop_via_label);
7763       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7764       if (0 != mp->next_hop_n_out_labels)
7765         {
7766           memcpy (mp->next_hop_out_label_stack,
7767                   next_hop_out_label_stack,
7768                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7769           vec_free (next_hop_out_label_stack);
7770         }
7771
7772       if (is_ipv6)
7773         {
7774           clib_memcpy (mp->dst_address, &v6_dst_address,
7775                        sizeof (v6_dst_address));
7776           if (next_hop_set)
7777             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7778                          sizeof (v6_next_hop_address));
7779           increment_v6_address (&v6_dst_address);
7780         }
7781       else
7782         {
7783           clib_memcpy (mp->dst_address, &v4_dst_address,
7784                        sizeof (v4_dst_address));
7785           if (next_hop_set)
7786             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7787                          sizeof (v4_next_hop_address));
7788           if (random_add_del)
7789             v4_dst_address.as_u32 = random_vector[j + 1];
7790           else
7791             increment_v4_address (&v4_dst_address);
7792         }
7793       /* send it... */
7794       S (mp);
7795       /* If we receive SIGTERM, stop now... */
7796       if (vam->do_exit)
7797         break;
7798     }
7799
7800   /* When testing multiple add/del ops, use a control-ping to sync */
7801   if (count > 1)
7802     {
7803       vl_api_control_ping_t *mp_ping;
7804       f64 after;
7805       f64 timeout;
7806
7807       /* Shut off async mode */
7808       vam->async_mode = 0;
7809
7810       MPING (CONTROL_PING, mp_ping);
7811       S (mp_ping);
7812
7813       timeout = vat_time_now (vam) + 1.0;
7814       while (vat_time_now (vam) < timeout)
7815         if (vam->result_ready == 1)
7816           goto out;
7817       vam->retval = -99;
7818
7819     out:
7820       if (vam->retval == -99)
7821         errmsg ("timeout");
7822
7823       if (vam->async_errors > 0)
7824         {
7825           errmsg ("%d asynchronous errors", vam->async_errors);
7826           vam->retval = -98;
7827         }
7828       vam->async_errors = 0;
7829       after = vat_time_now (vam);
7830
7831       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7832       if (j > 0)
7833         count = j;
7834
7835       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7836              count, after - before, count / (after - before));
7837     }
7838   else
7839     {
7840       int ret;
7841
7842       /* Wait for a reply... */
7843       W (ret);
7844       return ret;
7845     }
7846
7847   /* Return the good/bad news */
7848   return (vam->retval);
7849 }
7850
7851 static int
7852 api_ip_mroute_add_del (vat_main_t * vam)
7853 {
7854   unformat_input_t *i = vam->input;
7855   vl_api_ip_mroute_add_del_t *mp;
7856   u32 sw_if_index = ~0, vrf_id = 0;
7857   u8 is_ipv6 = 0;
7858   u8 is_local = 0;
7859   u8 create_vrf_if_needed = 0;
7860   u8 is_add = 1;
7861   u8 address_set = 0;
7862   u32 grp_address_length = 0;
7863   ip4_address_t v4_grp_address, v4_src_address;
7864   ip6_address_t v6_grp_address, v6_src_address;
7865   mfib_itf_flags_t iflags = 0;
7866   mfib_entry_flags_t eflags = 0;
7867   int ret;
7868
7869   /* Parse args required to build the message */
7870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7871     {
7872       if (unformat (i, "sw_if_index %d", &sw_if_index))
7873         ;
7874       else if (unformat (i, "%U %U",
7875                          unformat_ip4_address, &v4_src_address,
7876                          unformat_ip4_address, &v4_grp_address))
7877         {
7878           grp_address_length = 64;
7879           address_set = 1;
7880           is_ipv6 = 0;
7881         }
7882       else if (unformat (i, "%U %U",
7883                          unformat_ip6_address, &v6_src_address,
7884                          unformat_ip6_address, &v6_grp_address))
7885         {
7886           grp_address_length = 256;
7887           address_set = 1;
7888           is_ipv6 = 1;
7889         }
7890       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7891         {
7892           memset (&v4_src_address, 0, sizeof (v4_src_address));
7893           grp_address_length = 32;
7894           address_set = 1;
7895           is_ipv6 = 0;
7896         }
7897       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7898         {
7899           memset (&v6_src_address, 0, sizeof (v6_src_address));
7900           grp_address_length = 128;
7901           address_set = 1;
7902           is_ipv6 = 1;
7903         }
7904       else if (unformat (i, "/%d", &grp_address_length))
7905         ;
7906       else if (unformat (i, "local"))
7907         {
7908           is_local = 1;
7909         }
7910       else if (unformat (i, "del"))
7911         is_add = 0;
7912       else if (unformat (i, "add"))
7913         is_add = 1;
7914       else if (unformat (i, "vrf %d", &vrf_id))
7915         ;
7916       else if (unformat (i, "create-vrf"))
7917         create_vrf_if_needed = 1;
7918       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7919         ;
7920       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7921         ;
7922       else
7923         {
7924           clib_warning ("parse error '%U'", format_unformat_error, i);
7925           return -99;
7926         }
7927     }
7928
7929   if (address_set == 0)
7930     {
7931       errmsg ("missing addresses\n");
7932       return -99;
7933     }
7934
7935   /* Construct the API message */
7936   M (IP_MROUTE_ADD_DEL, mp);
7937
7938   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7939   mp->table_id = ntohl (vrf_id);
7940   mp->create_vrf_if_needed = create_vrf_if_needed;
7941
7942   mp->is_add = is_add;
7943   mp->is_ipv6 = is_ipv6;
7944   mp->is_local = is_local;
7945   mp->itf_flags = ntohl (iflags);
7946   mp->entry_flags = ntohl (eflags);
7947   mp->grp_address_length = grp_address_length;
7948   mp->grp_address_length = ntohs (mp->grp_address_length);
7949
7950   if (is_ipv6)
7951     {
7952       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7953       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7954     }
7955   else
7956     {
7957       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7958       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7959
7960     }
7961
7962   /* send it... */
7963   S (mp);
7964   /* Wait for a reply... */
7965   W (ret);
7966   return ret;
7967 }
7968
7969 static int
7970 api_mpls_table_add_del (vat_main_t * vam)
7971 {
7972   unformat_input_t *i = vam->input;
7973   vl_api_mpls_table_add_del_t *mp;
7974   u32 table_id = ~0;
7975   u8 is_add = 1;
7976   int ret = 0;
7977
7978   /* Parse args required to build the message */
7979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7980     {
7981       if (unformat (i, "table %d", &table_id))
7982         ;
7983       else if (unformat (i, "del"))
7984         is_add = 0;
7985       else if (unformat (i, "add"))
7986         is_add = 1;
7987       else
7988         {
7989           clib_warning ("parse error '%U'", format_unformat_error, i);
7990           return -99;
7991         }
7992     }
7993
7994   if (~0 == table_id)
7995     {
7996       errmsg ("missing table-ID");
7997       return -99;
7998     }
7999
8000   /* Construct the API message */
8001   M (MPLS_TABLE_ADD_DEL, mp);
8002
8003   mp->mt_table_id = ntohl (table_id);
8004   mp->mt_is_add = is_add;
8005
8006   /* send it... */
8007   S (mp);
8008
8009   /* Wait for a reply... */
8010   W (ret);
8011
8012   return ret;
8013 }
8014
8015 static int
8016 api_mpls_route_add_del (vat_main_t * vam)
8017 {
8018   unformat_input_t *i = vam->input;
8019   vl_api_mpls_route_add_del_t *mp;
8020   u32 sw_if_index = ~0, table_id = 0;
8021   u8 create_table_if_needed = 0;
8022   u8 is_add = 1;
8023   u32 next_hop_weight = 1;
8024   u8 is_multipath = 0;
8025   u32 next_hop_table_id = 0;
8026   u8 next_hop_set = 0;
8027   ip4_address_t v4_next_hop_address = {
8028     .as_u32 = 0,
8029   };
8030   ip6_address_t v6_next_hop_address = { {0} };
8031   int count = 1;
8032   int j;
8033   f64 before = 0;
8034   u32 classify_table_index = ~0;
8035   u8 is_classify = 0;
8036   u8 resolve_host = 0, resolve_attached = 0;
8037   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8038   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8039   mpls_label_t *next_hop_out_label_stack = NULL;
8040   mpls_label_t local_label = MPLS_LABEL_INVALID;
8041   u8 is_eos = 0;
8042   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8043
8044   /* Parse args required to build the message */
8045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8046     {
8047       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8048         ;
8049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8050         ;
8051       else if (unformat (i, "%d", &local_label))
8052         ;
8053       else if (unformat (i, "eos"))
8054         is_eos = 1;
8055       else if (unformat (i, "non-eos"))
8056         is_eos = 0;
8057       else if (unformat (i, "via %U", unformat_ip4_address,
8058                          &v4_next_hop_address))
8059         {
8060           next_hop_set = 1;
8061           next_hop_proto = DPO_PROTO_IP4;
8062         }
8063       else if (unformat (i, "via %U", unformat_ip6_address,
8064                          &v6_next_hop_address))
8065         {
8066           next_hop_set = 1;
8067           next_hop_proto = DPO_PROTO_IP6;
8068         }
8069       else if (unformat (i, "weight %d", &next_hop_weight))
8070         ;
8071       else if (unformat (i, "create-table"))
8072         create_table_if_needed = 1;
8073       else if (unformat (i, "classify %d", &classify_table_index))
8074         {
8075           is_classify = 1;
8076         }
8077       else if (unformat (i, "del"))
8078         is_add = 0;
8079       else if (unformat (i, "add"))
8080         is_add = 1;
8081       else if (unformat (i, "resolve-via-host"))
8082         resolve_host = 1;
8083       else if (unformat (i, "resolve-via-attached"))
8084         resolve_attached = 1;
8085       else if (unformat (i, "multipath"))
8086         is_multipath = 1;
8087       else if (unformat (i, "count %d", &count))
8088         ;
8089       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8090         {
8091           next_hop_set = 1;
8092           next_hop_proto = DPO_PROTO_IP4;
8093         }
8094       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8095         {
8096           next_hop_set = 1;
8097           next_hop_proto = DPO_PROTO_IP6;
8098         }
8099       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8100         ;
8101       else if (unformat (i, "via-label %d", &next_hop_via_label))
8102         ;
8103       else if (unformat (i, "out-label %d", &next_hop_out_label))
8104         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8105       else
8106         {
8107           clib_warning ("parse error '%U'", format_unformat_error, i);
8108           return -99;
8109         }
8110     }
8111
8112   if (!next_hop_set && !is_classify)
8113     {
8114       errmsg ("next hop / classify not set");
8115       return -99;
8116     }
8117
8118   if (MPLS_LABEL_INVALID == local_label)
8119     {
8120       errmsg ("missing label");
8121       return -99;
8122     }
8123
8124   if (count > 1)
8125     {
8126       /* Turn on async mode */
8127       vam->async_mode = 1;
8128       vam->async_errors = 0;
8129       before = vat_time_now (vam);
8130     }
8131
8132   for (j = 0; j < count; j++)
8133     {
8134       /* Construct the API message */
8135       M2 (MPLS_ROUTE_ADD_DEL, mp,
8136           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8137
8138       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8139       mp->mr_table_id = ntohl (table_id);
8140       mp->mr_create_table_if_needed = create_table_if_needed;
8141
8142       mp->mr_is_add = is_add;
8143       mp->mr_next_hop_proto = next_hop_proto;
8144       mp->mr_is_classify = is_classify;
8145       mp->mr_is_multipath = is_multipath;
8146       mp->mr_is_resolve_host = resolve_host;
8147       mp->mr_is_resolve_attached = resolve_attached;
8148       mp->mr_next_hop_weight = next_hop_weight;
8149       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8150       mp->mr_classify_table_index = ntohl (classify_table_index);
8151       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8152       mp->mr_label = ntohl (local_label);
8153       mp->mr_eos = is_eos;
8154
8155       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8156       if (0 != mp->mr_next_hop_n_out_labels)
8157         {
8158           memcpy (mp->mr_next_hop_out_label_stack,
8159                   next_hop_out_label_stack,
8160                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8161           vec_free (next_hop_out_label_stack);
8162         }
8163
8164       if (next_hop_set)
8165         {
8166           if (DPO_PROTO_IP4 == next_hop_proto)
8167             {
8168               clib_memcpy (mp->mr_next_hop,
8169                            &v4_next_hop_address,
8170                            sizeof (v4_next_hop_address));
8171             }
8172           else if (DPO_PROTO_IP6 == next_hop_proto)
8173
8174             {
8175               clib_memcpy (mp->mr_next_hop,
8176                            &v6_next_hop_address,
8177                            sizeof (v6_next_hop_address));
8178             }
8179         }
8180       local_label++;
8181
8182       /* send it... */
8183       S (mp);
8184       /* If we receive SIGTERM, stop now... */
8185       if (vam->do_exit)
8186         break;
8187     }
8188
8189   /* When testing multiple add/del ops, use a control-ping to sync */
8190   if (count > 1)
8191     {
8192       vl_api_control_ping_t *mp_ping;
8193       f64 after;
8194       f64 timeout;
8195
8196       /* Shut off async mode */
8197       vam->async_mode = 0;
8198
8199       MPING (CONTROL_PING, mp_ping);
8200       S (mp_ping);
8201
8202       timeout = vat_time_now (vam) + 1.0;
8203       while (vat_time_now (vam) < timeout)
8204         if (vam->result_ready == 1)
8205           goto out;
8206       vam->retval = -99;
8207
8208     out:
8209       if (vam->retval == -99)
8210         errmsg ("timeout");
8211
8212       if (vam->async_errors > 0)
8213         {
8214           errmsg ("%d asynchronous errors", vam->async_errors);
8215           vam->retval = -98;
8216         }
8217       vam->async_errors = 0;
8218       after = vat_time_now (vam);
8219
8220       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8221       if (j > 0)
8222         count = j;
8223
8224       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8225              count, after - before, count / (after - before));
8226     }
8227   else
8228     {
8229       int ret;
8230
8231       /* Wait for a reply... */
8232       W (ret);
8233       return ret;
8234     }
8235
8236   /* Return the good/bad news */
8237   return (vam->retval);
8238 }
8239
8240 static int
8241 api_mpls_ip_bind_unbind (vat_main_t * vam)
8242 {
8243   unformat_input_t *i = vam->input;
8244   vl_api_mpls_ip_bind_unbind_t *mp;
8245   u32 ip_table_id = 0;
8246   u8 create_table_if_needed = 0;
8247   u8 is_bind = 1;
8248   u8 is_ip4 = 1;
8249   ip4_address_t v4_address;
8250   ip6_address_t v6_address;
8251   u32 address_length;
8252   u8 address_set = 0;
8253   mpls_label_t local_label = MPLS_LABEL_INVALID;
8254   int ret;
8255
8256   /* Parse args required to build the message */
8257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8258     {
8259       if (unformat (i, "%U/%d", unformat_ip4_address,
8260                     &v4_address, &address_length))
8261         {
8262           is_ip4 = 1;
8263           address_set = 1;
8264         }
8265       else if (unformat (i, "%U/%d", unformat_ip6_address,
8266                          &v6_address, &address_length))
8267         {
8268           is_ip4 = 0;
8269           address_set = 1;
8270         }
8271       else if (unformat (i, "%d", &local_label))
8272         ;
8273       else if (unformat (i, "create-table"))
8274         create_table_if_needed = 1;
8275       else if (unformat (i, "table-id %d", &ip_table_id))
8276         ;
8277       else if (unformat (i, "unbind"))
8278         is_bind = 0;
8279       else if (unformat (i, "bind"))
8280         is_bind = 1;
8281       else
8282         {
8283           clib_warning ("parse error '%U'", format_unformat_error, i);
8284           return -99;
8285         }
8286     }
8287
8288   if (!address_set)
8289     {
8290       errmsg ("IP addres not set");
8291       return -99;
8292     }
8293
8294   if (MPLS_LABEL_INVALID == local_label)
8295     {
8296       errmsg ("missing label");
8297       return -99;
8298     }
8299
8300   /* Construct the API message */
8301   M (MPLS_IP_BIND_UNBIND, mp);
8302
8303   mp->mb_create_table_if_needed = create_table_if_needed;
8304   mp->mb_is_bind = is_bind;
8305   mp->mb_is_ip4 = is_ip4;
8306   mp->mb_ip_table_id = ntohl (ip_table_id);
8307   mp->mb_mpls_table_id = 0;
8308   mp->mb_label = ntohl (local_label);
8309   mp->mb_address_length = address_length;
8310
8311   if (is_ip4)
8312     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8313   else
8314     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8315
8316   /* send it... */
8317   S (mp);
8318
8319   /* Wait for a reply... */
8320   W (ret);
8321   return ret;
8322 }
8323
8324 static int
8325 api_proxy_arp_add_del (vat_main_t * vam)
8326 {
8327   unformat_input_t *i = vam->input;
8328   vl_api_proxy_arp_add_del_t *mp;
8329   u32 vrf_id = 0;
8330   u8 is_add = 1;
8331   ip4_address_t lo, hi;
8332   u8 range_set = 0;
8333   int ret;
8334
8335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8336     {
8337       if (unformat (i, "vrf %d", &vrf_id))
8338         ;
8339       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8340                          unformat_ip4_address, &hi))
8341         range_set = 1;
8342       else if (unformat (i, "del"))
8343         is_add = 0;
8344       else
8345         {
8346           clib_warning ("parse error '%U'", format_unformat_error, i);
8347           return -99;
8348         }
8349     }
8350
8351   if (range_set == 0)
8352     {
8353       errmsg ("address range not set");
8354       return -99;
8355     }
8356
8357   M (PROXY_ARP_ADD_DEL, mp);
8358
8359   mp->vrf_id = ntohl (vrf_id);
8360   mp->is_add = is_add;
8361   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8362   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8363
8364   S (mp);
8365   W (ret);
8366   return ret;
8367 }
8368
8369 static int
8370 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8371 {
8372   unformat_input_t *i = vam->input;
8373   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8374   u32 sw_if_index;
8375   u8 enable = 1;
8376   u8 sw_if_index_set = 0;
8377   int ret;
8378
8379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8382         sw_if_index_set = 1;
8383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8384         sw_if_index_set = 1;
8385       else if (unformat (i, "enable"))
8386         enable = 1;
8387       else if (unformat (i, "disable"))
8388         enable = 0;
8389       else
8390         {
8391           clib_warning ("parse error '%U'", format_unformat_error, i);
8392           return -99;
8393         }
8394     }
8395
8396   if (sw_if_index_set == 0)
8397     {
8398       errmsg ("missing interface name or sw_if_index");
8399       return -99;
8400     }
8401
8402   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8403
8404   mp->sw_if_index = ntohl (sw_if_index);
8405   mp->enable_disable = enable;
8406
8407   S (mp);
8408   W (ret);
8409   return ret;
8410 }
8411
8412 static int
8413 api_mpls_tunnel_add_del (vat_main_t * vam)
8414 {
8415   unformat_input_t *i = vam->input;
8416   vl_api_mpls_tunnel_add_del_t *mp;
8417
8418   u8 is_add = 1;
8419   u8 l2_only = 0;
8420   u32 sw_if_index = ~0;
8421   u32 next_hop_sw_if_index = ~0;
8422   u32 next_hop_proto_is_ip4 = 1;
8423
8424   u32 next_hop_table_id = 0;
8425   ip4_address_t v4_next_hop_address = {
8426     .as_u32 = 0,
8427   };
8428   ip6_address_t v6_next_hop_address = { {0} };
8429   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8430   int ret;
8431
8432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8433     {
8434       if (unformat (i, "add"))
8435         is_add = 1;
8436       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8437         is_add = 0;
8438       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8439         ;
8440       else if (unformat (i, "via %U",
8441                          unformat_ip4_address, &v4_next_hop_address))
8442         {
8443           next_hop_proto_is_ip4 = 1;
8444         }
8445       else if (unformat (i, "via %U",
8446                          unformat_ip6_address, &v6_next_hop_address))
8447         {
8448           next_hop_proto_is_ip4 = 0;
8449         }
8450       else if (unformat (i, "l2-only"))
8451         l2_only = 1;
8452       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8453         ;
8454       else if (unformat (i, "out-label %d", &next_hop_out_label))
8455         vec_add1 (labels, ntohl (next_hop_out_label));
8456       else
8457         {
8458           clib_warning ("parse error '%U'", format_unformat_error, i);
8459           return -99;
8460         }
8461     }
8462
8463   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8464
8465   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8466   mp->mt_sw_if_index = ntohl (sw_if_index);
8467   mp->mt_is_add = is_add;
8468   mp->mt_l2_only = l2_only;
8469   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8470   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8471
8472   mp->mt_next_hop_n_out_labels = vec_len (labels);
8473
8474   if (0 != mp->mt_next_hop_n_out_labels)
8475     {
8476       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8477                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8478       vec_free (labels);
8479     }
8480
8481   if (next_hop_proto_is_ip4)
8482     {
8483       clib_memcpy (mp->mt_next_hop,
8484                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8485     }
8486   else
8487     {
8488       clib_memcpy (mp->mt_next_hop,
8489                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8490     }
8491
8492   S (mp);
8493   W (ret);
8494   return ret;
8495 }
8496
8497 static int
8498 api_sw_interface_set_unnumbered (vat_main_t * vam)
8499 {
8500   unformat_input_t *i = vam->input;
8501   vl_api_sw_interface_set_unnumbered_t *mp;
8502   u32 sw_if_index;
8503   u32 unnum_sw_index = ~0;
8504   u8 is_add = 1;
8505   u8 sw_if_index_set = 0;
8506   int ret;
8507
8508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8509     {
8510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8511         sw_if_index_set = 1;
8512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8513         sw_if_index_set = 1;
8514       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8515         ;
8516       else if (unformat (i, "del"))
8517         is_add = 0;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (sw_if_index_set == 0)
8526     {
8527       errmsg ("missing interface name or sw_if_index");
8528       return -99;
8529     }
8530
8531   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8532
8533   mp->sw_if_index = ntohl (sw_if_index);
8534   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8535   mp->is_add = is_add;
8536
8537   S (mp);
8538   W (ret);
8539   return ret;
8540 }
8541
8542 static int
8543 api_ip_neighbor_add_del (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_ip_neighbor_add_del_t *mp;
8547   u32 sw_if_index;
8548   u8 sw_if_index_set = 0;
8549   u8 is_add = 1;
8550   u8 is_static = 0;
8551   u8 is_no_fib_entry = 0;
8552   u8 mac_address[6];
8553   u8 mac_set = 0;
8554   u8 v4_address_set = 0;
8555   u8 v6_address_set = 0;
8556   ip4_address_t v4address;
8557   ip6_address_t v6address;
8558   int ret;
8559
8560   memset (mac_address, 0, sizeof (mac_address));
8561
8562   /* Parse args required to build the message */
8563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8564     {
8565       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8566         {
8567           mac_set = 1;
8568         }
8569       else if (unformat (i, "del"))
8570         is_add = 0;
8571       else
8572         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8573         sw_if_index_set = 1;
8574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8575         sw_if_index_set = 1;
8576       else if (unformat (i, "is_static"))
8577         is_static = 1;
8578       else if (unformat (i, "no-fib-entry"))
8579         is_no_fib_entry = 1;
8580       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8581         v4_address_set = 1;
8582       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8583         v6_address_set = 1;
8584       else
8585         {
8586           clib_warning ("parse error '%U'", format_unformat_error, i);
8587           return -99;
8588         }
8589     }
8590
8591   if (sw_if_index_set == 0)
8592     {
8593       errmsg ("missing interface name or sw_if_index");
8594       return -99;
8595     }
8596   if (v4_address_set && v6_address_set)
8597     {
8598       errmsg ("both v4 and v6 addresses set");
8599       return -99;
8600     }
8601   if (!v4_address_set && !v6_address_set)
8602     {
8603       errmsg ("no address set");
8604       return -99;
8605     }
8606
8607   /* Construct the API message */
8608   M (IP_NEIGHBOR_ADD_DEL, mp);
8609
8610   mp->sw_if_index = ntohl (sw_if_index);
8611   mp->is_add = is_add;
8612   mp->is_static = is_static;
8613   mp->is_no_adj_fib = is_no_fib_entry;
8614   if (mac_set)
8615     clib_memcpy (mp->mac_address, mac_address, 6);
8616   if (v6_address_set)
8617     {
8618       mp->is_ipv6 = 1;
8619       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8620     }
8621   else
8622     {
8623       /* mp->is_ipv6 = 0; via memset in M macro above */
8624       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8625     }
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply, return good/bad news  */
8631   W (ret);
8632   return ret;
8633 }
8634
8635 static int
8636 api_reset_vrf (vat_main_t * vam)
8637 {
8638   unformat_input_t *i = vam->input;
8639   vl_api_reset_vrf_t *mp;
8640   u32 vrf_id = 0;
8641   u8 is_ipv6 = 0;
8642   u8 vrf_id_set = 0;
8643   int ret;
8644
8645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8646     {
8647       if (unformat (i, "vrf %d", &vrf_id))
8648         vrf_id_set = 1;
8649       else if (unformat (i, "ipv6"))
8650         is_ipv6 = 1;
8651       else
8652         {
8653           clib_warning ("parse error '%U'", format_unformat_error, i);
8654           return -99;
8655         }
8656     }
8657
8658   if (vrf_id_set == 0)
8659     {
8660       errmsg ("missing vrf id");
8661       return -99;
8662     }
8663
8664   M (RESET_VRF, mp);
8665
8666   mp->vrf_id = ntohl (vrf_id);
8667   mp->is_ipv6 = is_ipv6;
8668
8669   S (mp);
8670   W (ret);
8671   return ret;
8672 }
8673
8674 static int
8675 api_create_vlan_subif (vat_main_t * vam)
8676 {
8677   unformat_input_t *i = vam->input;
8678   vl_api_create_vlan_subif_t *mp;
8679   u32 sw_if_index;
8680   u8 sw_if_index_set = 0;
8681   u32 vlan_id;
8682   u8 vlan_id_set = 0;
8683   int ret;
8684
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "sw_if_index %d", &sw_if_index))
8688         sw_if_index_set = 1;
8689       else
8690         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8691         sw_if_index_set = 1;
8692       else if (unformat (i, "vlan %d", &vlan_id))
8693         vlan_id_set = 1;
8694       else
8695         {
8696           clib_warning ("parse error '%U'", format_unformat_error, i);
8697           return -99;
8698         }
8699     }
8700
8701   if (sw_if_index_set == 0)
8702     {
8703       errmsg ("missing interface name or sw_if_index");
8704       return -99;
8705     }
8706
8707   if (vlan_id_set == 0)
8708     {
8709       errmsg ("missing vlan_id");
8710       return -99;
8711     }
8712   M (CREATE_VLAN_SUBIF, mp);
8713
8714   mp->sw_if_index = ntohl (sw_if_index);
8715   mp->vlan_id = ntohl (vlan_id);
8716
8717   S (mp);
8718   W (ret);
8719   return ret;
8720 }
8721
8722 #define foreach_create_subif_bit                \
8723 _(no_tags)                                      \
8724 _(one_tag)                                      \
8725 _(two_tags)                                     \
8726 _(dot1ad)                                       \
8727 _(exact_match)                                  \
8728 _(default_sub)                                  \
8729 _(outer_vlan_id_any)                            \
8730 _(inner_vlan_id_any)
8731
8732 static int
8733 api_create_subif (vat_main_t * vam)
8734 {
8735   unformat_input_t *i = vam->input;
8736   vl_api_create_subif_t *mp;
8737   u32 sw_if_index;
8738   u8 sw_if_index_set = 0;
8739   u32 sub_id;
8740   u8 sub_id_set = 0;
8741   u32 no_tags = 0;
8742   u32 one_tag = 0;
8743   u32 two_tags = 0;
8744   u32 dot1ad = 0;
8745   u32 exact_match = 0;
8746   u32 default_sub = 0;
8747   u32 outer_vlan_id_any = 0;
8748   u32 inner_vlan_id_any = 0;
8749   u32 tmp;
8750   u16 outer_vlan_id = 0;
8751   u16 inner_vlan_id = 0;
8752   int ret;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "sw_if_index %d", &sw_if_index))
8757         sw_if_index_set = 1;
8758       else
8759         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8760         sw_if_index_set = 1;
8761       else if (unformat (i, "sub_id %d", &sub_id))
8762         sub_id_set = 1;
8763       else if (unformat (i, "outer_vlan_id %d", &tmp))
8764         outer_vlan_id = tmp;
8765       else if (unformat (i, "inner_vlan_id %d", &tmp))
8766         inner_vlan_id = tmp;
8767
8768 #define _(a) else if (unformat (i, #a)) a = 1 ;
8769       foreach_create_subif_bit
8770 #undef _
8771         else
8772         {
8773           clib_warning ("parse error '%U'", format_unformat_error, i);
8774           return -99;
8775         }
8776     }
8777
8778   if (sw_if_index_set == 0)
8779     {
8780       errmsg ("missing interface name or sw_if_index");
8781       return -99;
8782     }
8783
8784   if (sub_id_set == 0)
8785     {
8786       errmsg ("missing sub_id");
8787       return -99;
8788     }
8789   M (CREATE_SUBIF, mp);
8790
8791   mp->sw_if_index = ntohl (sw_if_index);
8792   mp->sub_id = ntohl (sub_id);
8793
8794 #define _(a) mp->a = a;
8795   foreach_create_subif_bit;
8796 #undef _
8797
8798   mp->outer_vlan_id = ntohs (outer_vlan_id);
8799   mp->inner_vlan_id = ntohs (inner_vlan_id);
8800
8801   S (mp);
8802   W (ret);
8803   return ret;
8804 }
8805
8806 static int
8807 api_oam_add_del (vat_main_t * vam)
8808 {
8809   unformat_input_t *i = vam->input;
8810   vl_api_oam_add_del_t *mp;
8811   u32 vrf_id = 0;
8812   u8 is_add = 1;
8813   ip4_address_t src, dst;
8814   u8 src_set = 0;
8815   u8 dst_set = 0;
8816   int ret;
8817
8818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8819     {
8820       if (unformat (i, "vrf %d", &vrf_id))
8821         ;
8822       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8823         src_set = 1;
8824       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8825         dst_set = 1;
8826       else if (unformat (i, "del"))
8827         is_add = 0;
8828       else
8829         {
8830           clib_warning ("parse error '%U'", format_unformat_error, i);
8831           return -99;
8832         }
8833     }
8834
8835   if (src_set == 0)
8836     {
8837       errmsg ("missing src addr");
8838       return -99;
8839     }
8840
8841   if (dst_set == 0)
8842     {
8843       errmsg ("missing dst addr");
8844       return -99;
8845     }
8846
8847   M (OAM_ADD_DEL, mp);
8848
8849   mp->vrf_id = ntohl (vrf_id);
8850   mp->is_add = is_add;
8851   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8852   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8853
8854   S (mp);
8855   W (ret);
8856   return ret;
8857 }
8858
8859 static int
8860 api_reset_fib (vat_main_t * vam)
8861 {
8862   unformat_input_t *i = vam->input;
8863   vl_api_reset_fib_t *mp;
8864   u32 vrf_id = 0;
8865   u8 is_ipv6 = 0;
8866   u8 vrf_id_set = 0;
8867
8868   int ret;
8869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8870     {
8871       if (unformat (i, "vrf %d", &vrf_id))
8872         vrf_id_set = 1;
8873       else if (unformat (i, "ipv6"))
8874         is_ipv6 = 1;
8875       else
8876         {
8877           clib_warning ("parse error '%U'", format_unformat_error, i);
8878           return -99;
8879         }
8880     }
8881
8882   if (vrf_id_set == 0)
8883     {
8884       errmsg ("missing vrf id");
8885       return -99;
8886     }
8887
8888   M (RESET_FIB, mp);
8889
8890   mp->vrf_id = ntohl (vrf_id);
8891   mp->is_ipv6 = is_ipv6;
8892
8893   S (mp);
8894   W (ret);
8895   return ret;
8896 }
8897
8898 static int
8899 api_dhcp_proxy_config (vat_main_t * vam)
8900 {
8901   unformat_input_t *i = vam->input;
8902   vl_api_dhcp_proxy_config_t *mp;
8903   u32 rx_vrf_id = 0;
8904   u32 server_vrf_id = 0;
8905   u8 is_add = 1;
8906   u8 v4_address_set = 0;
8907   u8 v6_address_set = 0;
8908   ip4_address_t v4address;
8909   ip6_address_t v6address;
8910   u8 v4_src_address_set = 0;
8911   u8 v6_src_address_set = 0;
8912   ip4_address_t v4srcaddress;
8913   ip6_address_t v6srcaddress;
8914   int ret;
8915
8916   /* Parse args required to build the message */
8917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8918     {
8919       if (unformat (i, "del"))
8920         is_add = 0;
8921       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8922         ;
8923       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8924         ;
8925       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8926         v4_address_set = 1;
8927       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8928         v6_address_set = 1;
8929       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8930         v4_src_address_set = 1;
8931       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8932         v6_src_address_set = 1;
8933       else
8934         break;
8935     }
8936
8937   if (v4_address_set && v6_address_set)
8938     {
8939       errmsg ("both v4 and v6 server addresses set");
8940       return -99;
8941     }
8942   if (!v4_address_set && !v6_address_set)
8943     {
8944       errmsg ("no server addresses set");
8945       return -99;
8946     }
8947
8948   if (v4_src_address_set && v6_src_address_set)
8949     {
8950       errmsg ("both v4 and v6  src addresses set");
8951       return -99;
8952     }
8953   if (!v4_src_address_set && !v6_src_address_set)
8954     {
8955       errmsg ("no src addresses set");
8956       return -99;
8957     }
8958
8959   if (!(v4_src_address_set && v4_address_set) &&
8960       !(v6_src_address_set && v6_address_set))
8961     {
8962       errmsg ("no matching server and src addresses set");
8963       return -99;
8964     }
8965
8966   /* Construct the API message */
8967   M (DHCP_PROXY_CONFIG, mp);
8968
8969   mp->is_add = is_add;
8970   mp->rx_vrf_id = ntohl (rx_vrf_id);
8971   mp->server_vrf_id = ntohl (server_vrf_id);
8972   if (v6_address_set)
8973     {
8974       mp->is_ipv6 = 1;
8975       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8976       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8977     }
8978   else
8979     {
8980       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8981       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8982     }
8983
8984   /* send it... */
8985   S (mp);
8986
8987   /* Wait for a reply, return good/bad news  */
8988   W (ret);
8989   return ret;
8990 }
8991
8992 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8993 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8994
8995 static void
8996 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8997 {
8998   vat_main_t *vam = &vat_main;
8999   u32 i, count = mp->count;
9000   vl_api_dhcp_server_t *s;
9001
9002   if (mp->is_ipv6)
9003     print (vam->ofp,
9004            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9005            ntohl (mp->rx_vrf_id),
9006            format_ip6_address, mp->dhcp_src_address,
9007            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9008   else
9009     print (vam->ofp,
9010            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9011            ntohl (mp->rx_vrf_id),
9012            format_ip4_address, mp->dhcp_src_address,
9013            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9014
9015   for (i = 0; i < count; i++)
9016     {
9017       s = &mp->servers[i];
9018
9019       if (mp->is_ipv6)
9020         print (vam->ofp,
9021                " Server Table-ID %d, Server Address %U",
9022                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9023       else
9024         print (vam->ofp,
9025                " Server Table-ID %d, Server Address %U",
9026                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9027     }
9028 }
9029
9030 static void vl_api_dhcp_proxy_details_t_handler_json
9031   (vl_api_dhcp_proxy_details_t * mp)
9032 {
9033   vat_main_t *vam = &vat_main;
9034   vat_json_node_t *node = NULL;
9035   u32 i, count = mp->count;
9036   struct in_addr ip4;
9037   struct in6_addr ip6;
9038   vl_api_dhcp_server_t *s;
9039
9040   if (VAT_JSON_ARRAY != vam->json_tree.type)
9041     {
9042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9043       vat_json_init_array (&vam->json_tree);
9044     }
9045   node = vat_json_array_add (&vam->json_tree);
9046
9047   vat_json_init_object (node);
9048   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9049   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9050   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9051
9052   if (mp->is_ipv6)
9053     {
9054       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9055       vat_json_object_add_ip6 (node, "src_address", ip6);
9056     }
9057   else
9058     {
9059       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9060       vat_json_object_add_ip4 (node, "src_address", ip4);
9061     }
9062
9063   for (i = 0; i < count; i++)
9064     {
9065       s = &mp->servers[i];
9066
9067       vat_json_object_add_uint (node, "server-table-id",
9068                                 ntohl (s->server_vrf_id));
9069
9070       if (mp->is_ipv6)
9071         {
9072           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9073           vat_json_object_add_ip4 (node, "src_address", ip4);
9074         }
9075       else
9076         {
9077           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9078           vat_json_object_add_ip6 (node, "server_address", ip6);
9079         }
9080     }
9081 }
9082
9083 static int
9084 api_dhcp_proxy_dump (vat_main_t * vam)
9085 {
9086   unformat_input_t *i = vam->input;
9087   vl_api_control_ping_t *mp_ping;
9088   vl_api_dhcp_proxy_dump_t *mp;
9089   u8 is_ipv6 = 0;
9090   int ret;
9091
9092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9093     {
9094       if (unformat (i, "ipv6"))
9095         is_ipv6 = 1;
9096       else
9097         {
9098           clib_warning ("parse error '%U'", format_unformat_error, i);
9099           return -99;
9100         }
9101     }
9102
9103   M (DHCP_PROXY_DUMP, mp);
9104
9105   mp->is_ip6 = is_ipv6;
9106   S (mp);
9107
9108   /* Use a control ping for synchronization */
9109   MPING (CONTROL_PING, mp_ping);
9110   S (mp_ping);
9111
9112   W (ret);
9113   return ret;
9114 }
9115
9116 static int
9117 api_dhcp_proxy_set_vss (vat_main_t * vam)
9118 {
9119   unformat_input_t *i = vam->input;
9120   vl_api_dhcp_proxy_set_vss_t *mp;
9121   u8 is_ipv6 = 0;
9122   u8 is_add = 1;
9123   u32 tbl_id;
9124   u8 tbl_id_set = 0;
9125   u32 oui;
9126   u8 oui_set = 0;
9127   u32 fib_id;
9128   u8 fib_id_set = 0;
9129   int ret;
9130
9131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9132     {
9133       if (unformat (i, "tbl_id %d", &tbl_id))
9134         tbl_id_set = 1;
9135       if (unformat (i, "fib_id %d", &fib_id))
9136         fib_id_set = 1;
9137       if (unformat (i, "oui %d", &oui))
9138         oui_set = 1;
9139       else if (unformat (i, "ipv6"))
9140         is_ipv6 = 1;
9141       else if (unformat (i, "del"))
9142         is_add = 0;
9143       else
9144         {
9145           clib_warning ("parse error '%U'", format_unformat_error, i);
9146           return -99;
9147         }
9148     }
9149
9150   if (tbl_id_set == 0)
9151     {
9152       errmsg ("missing tbl id");
9153       return -99;
9154     }
9155
9156   if (fib_id_set == 0)
9157     {
9158       errmsg ("missing fib id");
9159       return -99;
9160     }
9161   if (oui_set == 0)
9162     {
9163       errmsg ("missing oui");
9164       return -99;
9165     }
9166
9167   M (DHCP_PROXY_SET_VSS, mp);
9168   mp->tbl_id = ntohl (tbl_id);
9169   mp->fib_id = ntohl (fib_id);
9170   mp->oui = ntohl (oui);
9171   mp->is_ipv6 = is_ipv6;
9172   mp->is_add = is_add;
9173
9174   S (mp);
9175   W (ret);
9176   return ret;
9177 }
9178
9179 static int
9180 api_dhcp_client_config (vat_main_t * vam)
9181 {
9182   unformat_input_t *i = vam->input;
9183   vl_api_dhcp_client_config_t *mp;
9184   u32 sw_if_index;
9185   u8 sw_if_index_set = 0;
9186   u8 is_add = 1;
9187   u8 *hostname = 0;
9188   u8 disable_event = 0;
9189   int ret;
9190
9191   /* Parse args required to build the message */
9192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9193     {
9194       if (unformat (i, "del"))
9195         is_add = 0;
9196       else
9197         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9198         sw_if_index_set = 1;
9199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9200         sw_if_index_set = 1;
9201       else if (unformat (i, "hostname %s", &hostname))
9202         ;
9203       else if (unformat (i, "disable_event"))
9204         disable_event = 1;
9205       else
9206         break;
9207     }
9208
9209   if (sw_if_index_set == 0)
9210     {
9211       errmsg ("missing interface name or sw_if_index");
9212       return -99;
9213     }
9214
9215   if (vec_len (hostname) > 63)
9216     {
9217       errmsg ("hostname too long");
9218     }
9219   vec_add1 (hostname, 0);
9220
9221   /* Construct the API message */
9222   M (DHCP_CLIENT_CONFIG, mp);
9223
9224   mp->sw_if_index = htonl (sw_if_index);
9225   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9226   vec_free (hostname);
9227   mp->is_add = is_add;
9228   mp->want_dhcp_event = disable_event ? 0 : 1;
9229   mp->pid = htonl (getpid ());
9230
9231   /* send it... */
9232   S (mp);
9233
9234   /* Wait for a reply, return good/bad news  */
9235   W (ret);
9236   return ret;
9237 }
9238
9239 static int
9240 api_set_ip_flow_hash (vat_main_t * vam)
9241 {
9242   unformat_input_t *i = vam->input;
9243   vl_api_set_ip_flow_hash_t *mp;
9244   u32 vrf_id = 0;
9245   u8 is_ipv6 = 0;
9246   u8 vrf_id_set = 0;
9247   u8 src = 0;
9248   u8 dst = 0;
9249   u8 sport = 0;
9250   u8 dport = 0;
9251   u8 proto = 0;
9252   u8 reverse = 0;
9253   int ret;
9254
9255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9256     {
9257       if (unformat (i, "vrf %d", &vrf_id))
9258         vrf_id_set = 1;
9259       else if (unformat (i, "ipv6"))
9260         is_ipv6 = 1;
9261       else if (unformat (i, "src"))
9262         src = 1;
9263       else if (unformat (i, "dst"))
9264         dst = 1;
9265       else if (unformat (i, "sport"))
9266         sport = 1;
9267       else if (unformat (i, "dport"))
9268         dport = 1;
9269       else if (unformat (i, "proto"))
9270         proto = 1;
9271       else if (unformat (i, "reverse"))
9272         reverse = 1;
9273
9274       else
9275         {
9276           clib_warning ("parse error '%U'", format_unformat_error, i);
9277           return -99;
9278         }
9279     }
9280
9281   if (vrf_id_set == 0)
9282     {
9283       errmsg ("missing vrf id");
9284       return -99;
9285     }
9286
9287   M (SET_IP_FLOW_HASH, mp);
9288   mp->src = src;
9289   mp->dst = dst;
9290   mp->sport = sport;
9291   mp->dport = dport;
9292   mp->proto = proto;
9293   mp->reverse = reverse;
9294   mp->vrf_id = ntohl (vrf_id);
9295   mp->is_ipv6 = is_ipv6;
9296
9297   S (mp);
9298   W (ret);
9299   return ret;
9300 }
9301
9302 static int
9303 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9304 {
9305   unformat_input_t *i = vam->input;
9306   vl_api_sw_interface_ip6_enable_disable_t *mp;
9307   u32 sw_if_index;
9308   u8 sw_if_index_set = 0;
9309   u8 enable = 0;
9310   int ret;
9311
9312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9313     {
9314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9315         sw_if_index_set = 1;
9316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9317         sw_if_index_set = 1;
9318       else if (unformat (i, "enable"))
9319         enable = 1;
9320       else if (unformat (i, "disable"))
9321         enable = 0;
9322       else
9323         {
9324           clib_warning ("parse error '%U'", format_unformat_error, i);
9325           return -99;
9326         }
9327     }
9328
9329   if (sw_if_index_set == 0)
9330     {
9331       errmsg ("missing interface name or sw_if_index");
9332       return -99;
9333     }
9334
9335   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9336
9337   mp->sw_if_index = ntohl (sw_if_index);
9338   mp->enable = enable;
9339
9340   S (mp);
9341   W (ret);
9342   return ret;
9343 }
9344
9345 static int
9346 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9347 {
9348   unformat_input_t *i = vam->input;
9349   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9350   u32 sw_if_index;
9351   u8 sw_if_index_set = 0;
9352   u8 v6_address_set = 0;
9353   ip6_address_t v6address;
9354   int ret;
9355
9356   /* Parse args required to build the message */
9357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9358     {
9359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9360         sw_if_index_set = 1;
9361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9364         v6_address_set = 1;
9365       else
9366         break;
9367     }
9368
9369   if (sw_if_index_set == 0)
9370     {
9371       errmsg ("missing interface name or sw_if_index");
9372       return -99;
9373     }
9374   if (!v6_address_set)
9375     {
9376       errmsg ("no address set");
9377       return -99;
9378     }
9379
9380   /* Construct the API message */
9381   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9382
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9385
9386   /* send it... */
9387   S (mp);
9388
9389   /* Wait for a reply, return good/bad news  */
9390   W (ret);
9391   return ret;
9392 }
9393
9394 static int
9395 api_ip6nd_proxy_add_del (vat_main_t * vam)
9396 {
9397   unformat_input_t *i = vam->input;
9398   vl_api_ip6nd_proxy_add_del_t *mp;
9399   u32 sw_if_index = ~0;
9400   u8 v6_address_set = 0;
9401   ip6_address_t v6address;
9402   u8 is_del = 0;
9403   int ret;
9404
9405   /* Parse args required to build the message */
9406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9407     {
9408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9409         ;
9410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9411         ;
9412       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9413         v6_address_set = 1;
9414       if (unformat (i, "del"))
9415         is_del = 1;
9416       else
9417         {
9418           clib_warning ("parse error '%U'", format_unformat_error, i);
9419           return -99;
9420         }
9421     }
9422
9423   if (sw_if_index == ~0)
9424     {
9425       errmsg ("missing interface name or sw_if_index");
9426       return -99;
9427     }
9428   if (!v6_address_set)
9429     {
9430       errmsg ("no address set");
9431       return -99;
9432     }
9433
9434   /* Construct the API message */
9435   M (IP6ND_PROXY_ADD_DEL, mp);
9436
9437   mp->is_del = is_del;
9438   mp->sw_if_index = ntohl (sw_if_index);
9439   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9440
9441   /* send it... */
9442   S (mp);
9443
9444   /* Wait for a reply, return good/bad news  */
9445   W (ret);
9446   return ret;
9447 }
9448
9449 static int
9450 api_ip6nd_proxy_dump (vat_main_t * vam)
9451 {
9452   vl_api_ip6nd_proxy_dump_t *mp;
9453   vl_api_control_ping_t *mp_ping;
9454   int ret;
9455
9456   M (IP6ND_PROXY_DUMP, mp);
9457
9458   S (mp);
9459
9460   /* Use a control ping for synchronization */
9461   MPING (CONTROL_PING, mp_ping);
9462   S (mp_ping);
9463
9464   W (ret);
9465   return ret;
9466 }
9467
9468 static void vl_api_ip6nd_proxy_details_t_handler
9469   (vl_api_ip6nd_proxy_details_t * mp)
9470 {
9471   vat_main_t *vam = &vat_main;
9472
9473   print (vam->ofp, "host %U sw_if_index %d",
9474          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9475 }
9476
9477 static void vl_api_ip6nd_proxy_details_t_handler_json
9478   (vl_api_ip6nd_proxy_details_t * mp)
9479 {
9480   vat_main_t *vam = &vat_main;
9481   struct in6_addr ip6;
9482   vat_json_node_t *node = NULL;
9483
9484   if (VAT_JSON_ARRAY != vam->json_tree.type)
9485     {
9486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9487       vat_json_init_array (&vam->json_tree);
9488     }
9489   node = vat_json_array_add (&vam->json_tree);
9490
9491   vat_json_init_object (node);
9492   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9493
9494   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9495   vat_json_object_add_ip6 (node, "host", ip6);
9496 }
9497
9498 static int
9499 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9500 {
9501   unformat_input_t *i = vam->input;
9502   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9503   u32 sw_if_index;
9504   u8 sw_if_index_set = 0;
9505   u32 address_length = 0;
9506   u8 v6_address_set = 0;
9507   ip6_address_t v6address;
9508   u8 use_default = 0;
9509   u8 no_advertise = 0;
9510   u8 off_link = 0;
9511   u8 no_autoconfig = 0;
9512   u8 no_onlink = 0;
9513   u8 is_no = 0;
9514   u32 val_lifetime = 0;
9515   u32 pref_lifetime = 0;
9516   int ret;
9517
9518   /* Parse args required to build the message */
9519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9520     {
9521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9522         sw_if_index_set = 1;
9523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9524         sw_if_index_set = 1;
9525       else if (unformat (i, "%U/%d",
9526                          unformat_ip6_address, &v6address, &address_length))
9527         v6_address_set = 1;
9528       else if (unformat (i, "val_life %d", &val_lifetime))
9529         ;
9530       else if (unformat (i, "pref_life %d", &pref_lifetime))
9531         ;
9532       else if (unformat (i, "def"))
9533         use_default = 1;
9534       else if (unformat (i, "noadv"))
9535         no_advertise = 1;
9536       else if (unformat (i, "offl"))
9537         off_link = 1;
9538       else if (unformat (i, "noauto"))
9539         no_autoconfig = 1;
9540       else if (unformat (i, "nolink"))
9541         no_onlink = 1;
9542       else if (unformat (i, "isno"))
9543         is_no = 1;
9544       else
9545         {
9546           clib_warning ("parse error '%U'", format_unformat_error, i);
9547           return -99;
9548         }
9549     }
9550
9551   if (sw_if_index_set == 0)
9552     {
9553       errmsg ("missing interface name or sw_if_index");
9554       return -99;
9555     }
9556   if (!v6_address_set)
9557     {
9558       errmsg ("no address set");
9559       return -99;
9560     }
9561
9562   /* Construct the API message */
9563   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9564
9565   mp->sw_if_index = ntohl (sw_if_index);
9566   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9567   mp->address_length = address_length;
9568   mp->use_default = use_default;
9569   mp->no_advertise = no_advertise;
9570   mp->off_link = off_link;
9571   mp->no_autoconfig = no_autoconfig;
9572   mp->no_onlink = no_onlink;
9573   mp->is_no = is_no;
9574   mp->val_lifetime = ntohl (val_lifetime);
9575   mp->pref_lifetime = ntohl (pref_lifetime);
9576
9577   /* send it... */
9578   S (mp);
9579
9580   /* Wait for a reply, return good/bad news  */
9581   W (ret);
9582   return ret;
9583 }
9584
9585 static int
9586 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9587 {
9588   unformat_input_t *i = vam->input;
9589   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9590   u32 sw_if_index;
9591   u8 sw_if_index_set = 0;
9592   u8 suppress = 0;
9593   u8 managed = 0;
9594   u8 other = 0;
9595   u8 ll_option = 0;
9596   u8 send_unicast = 0;
9597   u8 cease = 0;
9598   u8 is_no = 0;
9599   u8 default_router = 0;
9600   u32 max_interval = 0;
9601   u32 min_interval = 0;
9602   u32 lifetime = 0;
9603   u32 initial_count = 0;
9604   u32 initial_interval = 0;
9605   int ret;
9606
9607
9608   /* Parse args required to build the message */
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9612         sw_if_index_set = 1;
9613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9614         sw_if_index_set = 1;
9615       else if (unformat (i, "maxint %d", &max_interval))
9616         ;
9617       else if (unformat (i, "minint %d", &min_interval))
9618         ;
9619       else if (unformat (i, "life %d", &lifetime))
9620         ;
9621       else if (unformat (i, "count %d", &initial_count))
9622         ;
9623       else if (unformat (i, "interval %d", &initial_interval))
9624         ;
9625       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9626         suppress = 1;
9627       else if (unformat (i, "managed"))
9628         managed = 1;
9629       else if (unformat (i, "other"))
9630         other = 1;
9631       else if (unformat (i, "ll"))
9632         ll_option = 1;
9633       else if (unformat (i, "send"))
9634         send_unicast = 1;
9635       else if (unformat (i, "cease"))
9636         cease = 1;
9637       else if (unformat (i, "isno"))
9638         is_no = 1;
9639       else if (unformat (i, "def"))
9640         default_router = 1;
9641       else
9642         {
9643           clib_warning ("parse error '%U'", format_unformat_error, i);
9644           return -99;
9645         }
9646     }
9647
9648   if (sw_if_index_set == 0)
9649     {
9650       errmsg ("missing interface name or sw_if_index");
9651       return -99;
9652     }
9653
9654   /* Construct the API message */
9655   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9656
9657   mp->sw_if_index = ntohl (sw_if_index);
9658   mp->max_interval = ntohl (max_interval);
9659   mp->min_interval = ntohl (min_interval);
9660   mp->lifetime = ntohl (lifetime);
9661   mp->initial_count = ntohl (initial_count);
9662   mp->initial_interval = ntohl (initial_interval);
9663   mp->suppress = suppress;
9664   mp->managed = managed;
9665   mp->other = other;
9666   mp->ll_option = ll_option;
9667   mp->send_unicast = send_unicast;
9668   mp->cease = cease;
9669   mp->is_no = is_no;
9670   mp->default_router = default_router;
9671
9672   /* send it... */
9673   S (mp);
9674
9675   /* Wait for a reply, return good/bad news  */
9676   W (ret);
9677   return ret;
9678 }
9679
9680 static int
9681 api_set_arp_neighbor_limit (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_set_arp_neighbor_limit_t *mp;
9685   u32 arp_nbr_limit;
9686   u8 limit_set = 0;
9687   u8 is_ipv6 = 0;
9688   int ret;
9689
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9693         limit_set = 1;
9694       else if (unformat (i, "ipv6"))
9695         is_ipv6 = 1;
9696       else
9697         {
9698           clib_warning ("parse error '%U'", format_unformat_error, i);
9699           return -99;
9700         }
9701     }
9702
9703   if (limit_set == 0)
9704     {
9705       errmsg ("missing limit value");
9706       return -99;
9707     }
9708
9709   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9710
9711   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9712   mp->is_ipv6 = is_ipv6;
9713
9714   S (mp);
9715   W (ret);
9716   return ret;
9717 }
9718
9719 static int
9720 api_l2_patch_add_del (vat_main_t * vam)
9721 {
9722   unformat_input_t *i = vam->input;
9723   vl_api_l2_patch_add_del_t *mp;
9724   u32 rx_sw_if_index;
9725   u8 rx_sw_if_index_set = 0;
9726   u32 tx_sw_if_index;
9727   u8 tx_sw_if_index_set = 0;
9728   u8 is_add = 1;
9729   int ret;
9730
9731   /* Parse args required to build the message */
9732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9733     {
9734       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9735         rx_sw_if_index_set = 1;
9736       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9737         tx_sw_if_index_set = 1;
9738       else if (unformat (i, "rx"))
9739         {
9740           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9741             {
9742               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9743                             &rx_sw_if_index))
9744                 rx_sw_if_index_set = 1;
9745             }
9746           else
9747             break;
9748         }
9749       else if (unformat (i, "tx"))
9750         {
9751           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752             {
9753               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9754                             &tx_sw_if_index))
9755                 tx_sw_if_index_set = 1;
9756             }
9757           else
9758             break;
9759         }
9760       else if (unformat (i, "del"))
9761         is_add = 0;
9762       else
9763         break;
9764     }
9765
9766   if (rx_sw_if_index_set == 0)
9767     {
9768       errmsg ("missing rx interface name or rx_sw_if_index");
9769       return -99;
9770     }
9771
9772   if (tx_sw_if_index_set == 0)
9773     {
9774       errmsg ("missing tx interface name or tx_sw_if_index");
9775       return -99;
9776     }
9777
9778   M (L2_PATCH_ADD_DEL, mp);
9779
9780   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9781   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9782   mp->is_add = is_add;
9783
9784   S (mp);
9785   W (ret);
9786   return ret;
9787 }
9788
9789 u8 is_del;
9790 u8 localsid_addr[16];
9791 u8 end_psp;
9792 u8 behavior;
9793 u32 sw_if_index;
9794 u32 vlan_index;
9795 u32 fib_table;
9796 u8 nh_addr[16];
9797
9798 static int
9799 api_sr_localsid_add_del (vat_main_t * vam)
9800 {
9801   unformat_input_t *i = vam->input;
9802   vl_api_sr_localsid_add_del_t *mp;
9803
9804   u8 is_del;
9805   ip6_address_t localsid;
9806   u8 end_psp = 0;
9807   u8 behavior = ~0;
9808   u32 sw_if_index;
9809   u32 fib_table = ~(u32) 0;
9810   ip6_address_t next_hop;
9811
9812   bool nexthop_set = 0;
9813
9814   int ret;
9815
9816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9817     {
9818       if (unformat (i, "del"))
9819         is_del = 1;
9820       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9821       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9822         nexthop_set = 1;
9823       else if (unformat (i, "behavior %u", &behavior));
9824       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9825       else if (unformat (i, "fib-table %u", &fib_table));
9826       else if (unformat (i, "end.psp %u", &behavior));
9827       else
9828         break;
9829     }
9830
9831   M (SR_LOCALSID_ADD_DEL, mp);
9832
9833   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9834   if (nexthop_set)
9835     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9836   mp->behavior = behavior;
9837   mp->sw_if_index = ntohl (sw_if_index);
9838   mp->fib_table = ntohl (fib_table);
9839   mp->end_psp = end_psp;
9840   mp->is_del = is_del;
9841
9842   S (mp);
9843   W (ret);
9844   return ret;
9845 }
9846
9847 static int
9848 api_ioam_enable (vat_main_t * vam)
9849 {
9850   unformat_input_t *input = vam->input;
9851   vl_api_ioam_enable_t *mp;
9852   u32 id = 0;
9853   int has_trace_option = 0;
9854   int has_pot_option = 0;
9855   int has_seqno_option = 0;
9856   int has_analyse_option = 0;
9857   int ret;
9858
9859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9860     {
9861       if (unformat (input, "trace"))
9862         has_trace_option = 1;
9863       else if (unformat (input, "pot"))
9864         has_pot_option = 1;
9865       else if (unformat (input, "seqno"))
9866         has_seqno_option = 1;
9867       else if (unformat (input, "analyse"))
9868         has_analyse_option = 1;
9869       else
9870         break;
9871     }
9872   M (IOAM_ENABLE, mp);
9873   mp->id = htons (id);
9874   mp->seqno = has_seqno_option;
9875   mp->analyse = has_analyse_option;
9876   mp->pot_enable = has_pot_option;
9877   mp->trace_enable = has_trace_option;
9878
9879   S (mp);
9880   W (ret);
9881   return ret;
9882 }
9883
9884
9885 static int
9886 api_ioam_disable (vat_main_t * vam)
9887 {
9888   vl_api_ioam_disable_t *mp;
9889   int ret;
9890
9891   M (IOAM_DISABLE, mp);
9892   S (mp);
9893   W (ret);
9894   return ret;
9895 }
9896
9897 #define foreach_tcp_proto_field                 \
9898 _(src_port)                                     \
9899 _(dst_port)
9900
9901 #define foreach_udp_proto_field                 \
9902 _(src_port)                                     \
9903 _(dst_port)
9904
9905 #define foreach_ip4_proto_field                 \
9906 _(src_address)                                  \
9907 _(dst_address)                                  \
9908 _(tos)                                          \
9909 _(length)                                       \
9910 _(fragment_id)                                  \
9911 _(ttl)                                          \
9912 _(protocol)                                     \
9913 _(checksum)
9914
9915 typedef struct
9916 {
9917   u16 src_port, dst_port;
9918 } tcpudp_header_t;
9919
9920 #if VPP_API_TEST_BUILTIN == 0
9921 uword
9922 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9923 {
9924   u8 **maskp = va_arg (*args, u8 **);
9925   u8 *mask = 0;
9926   u8 found_something = 0;
9927   tcp_header_t *tcp;
9928
9929 #define _(a) u8 a=0;
9930   foreach_tcp_proto_field;
9931 #undef _
9932
9933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9934     {
9935       if (0);
9936 #define _(a) else if (unformat (input, #a)) a=1;
9937       foreach_tcp_proto_field
9938 #undef _
9939         else
9940         break;
9941     }
9942
9943 #define _(a) found_something += a;
9944   foreach_tcp_proto_field;
9945 #undef _
9946
9947   if (found_something == 0)
9948     return 0;
9949
9950   vec_validate (mask, sizeof (*tcp) - 1);
9951
9952   tcp = (tcp_header_t *) mask;
9953
9954 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9955   foreach_tcp_proto_field;
9956 #undef _
9957
9958   *maskp = mask;
9959   return 1;
9960 }
9961
9962 uword
9963 unformat_udp_mask (unformat_input_t * input, va_list * args)
9964 {
9965   u8 **maskp = va_arg (*args, u8 **);
9966   u8 *mask = 0;
9967   u8 found_something = 0;
9968   udp_header_t *udp;
9969
9970 #define _(a) u8 a=0;
9971   foreach_udp_proto_field;
9972 #undef _
9973
9974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9975     {
9976       if (0);
9977 #define _(a) else if (unformat (input, #a)) a=1;
9978       foreach_udp_proto_field
9979 #undef _
9980         else
9981         break;
9982     }
9983
9984 #define _(a) found_something += a;
9985   foreach_udp_proto_field;
9986 #undef _
9987
9988   if (found_something == 0)
9989     return 0;
9990
9991   vec_validate (mask, sizeof (*udp) - 1);
9992
9993   udp = (udp_header_t *) mask;
9994
9995 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9996   foreach_udp_proto_field;
9997 #undef _
9998
9999   *maskp = mask;
10000   return 1;
10001 }
10002
10003 uword
10004 unformat_l4_mask (unformat_input_t * input, va_list * args)
10005 {
10006   u8 **maskp = va_arg (*args, u8 **);
10007   u16 src_port = 0, dst_port = 0;
10008   tcpudp_header_t *tcpudp;
10009
10010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10011     {
10012       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10013         return 1;
10014       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10015         return 1;
10016       else if (unformat (input, "src_port"))
10017         src_port = 0xFFFF;
10018       else if (unformat (input, "dst_port"))
10019         dst_port = 0xFFFF;
10020       else
10021         return 0;
10022     }
10023
10024   if (!src_port && !dst_port)
10025     return 0;
10026
10027   u8 *mask = 0;
10028   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10029
10030   tcpudp = (tcpudp_header_t *) mask;
10031   tcpudp->src_port = src_port;
10032   tcpudp->dst_port = dst_port;
10033
10034   *maskp = mask;
10035
10036   return 1;
10037 }
10038
10039 uword
10040 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10041 {
10042   u8 **maskp = va_arg (*args, u8 **);
10043   u8 *mask = 0;
10044   u8 found_something = 0;
10045   ip4_header_t *ip;
10046
10047 #define _(a) u8 a=0;
10048   foreach_ip4_proto_field;
10049 #undef _
10050   u8 version = 0;
10051   u8 hdr_length = 0;
10052
10053
10054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10055     {
10056       if (unformat (input, "version"))
10057         version = 1;
10058       else if (unformat (input, "hdr_length"))
10059         hdr_length = 1;
10060       else if (unformat (input, "src"))
10061         src_address = 1;
10062       else if (unformat (input, "dst"))
10063         dst_address = 1;
10064       else if (unformat (input, "proto"))
10065         protocol = 1;
10066
10067 #define _(a) else if (unformat (input, #a)) a=1;
10068       foreach_ip4_proto_field
10069 #undef _
10070         else
10071         break;
10072     }
10073
10074 #define _(a) found_something += a;
10075   foreach_ip4_proto_field;
10076 #undef _
10077
10078   if (found_something == 0)
10079     return 0;
10080
10081   vec_validate (mask, sizeof (*ip) - 1);
10082
10083   ip = (ip4_header_t *) mask;
10084
10085 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10086   foreach_ip4_proto_field;
10087 #undef _
10088
10089   ip->ip_version_and_header_length = 0;
10090
10091   if (version)
10092     ip->ip_version_and_header_length |= 0xF0;
10093
10094   if (hdr_length)
10095     ip->ip_version_and_header_length |= 0x0F;
10096
10097   *maskp = mask;
10098   return 1;
10099 }
10100
10101 #define foreach_ip6_proto_field                 \
10102 _(src_address)                                  \
10103 _(dst_address)                                  \
10104 _(payload_length)                               \
10105 _(hop_limit)                                    \
10106 _(protocol)
10107
10108 uword
10109 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10110 {
10111   u8 **maskp = va_arg (*args, u8 **);
10112   u8 *mask = 0;
10113   u8 found_something = 0;
10114   ip6_header_t *ip;
10115   u32 ip_version_traffic_class_and_flow_label;
10116
10117 #define _(a) u8 a=0;
10118   foreach_ip6_proto_field;
10119 #undef _
10120   u8 version = 0;
10121   u8 traffic_class = 0;
10122   u8 flow_label = 0;
10123
10124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10125     {
10126       if (unformat (input, "version"))
10127         version = 1;
10128       else if (unformat (input, "traffic-class"))
10129         traffic_class = 1;
10130       else if (unformat (input, "flow-label"))
10131         flow_label = 1;
10132       else if (unformat (input, "src"))
10133         src_address = 1;
10134       else if (unformat (input, "dst"))
10135         dst_address = 1;
10136       else if (unformat (input, "proto"))
10137         protocol = 1;
10138
10139 #define _(a) else if (unformat (input, #a)) a=1;
10140       foreach_ip6_proto_field
10141 #undef _
10142         else
10143         break;
10144     }
10145
10146 #define _(a) found_something += a;
10147   foreach_ip6_proto_field;
10148 #undef _
10149
10150   if (found_something == 0)
10151     return 0;
10152
10153   vec_validate (mask, sizeof (*ip) - 1);
10154
10155   ip = (ip6_header_t *) mask;
10156
10157 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10158   foreach_ip6_proto_field;
10159 #undef _
10160
10161   ip_version_traffic_class_and_flow_label = 0;
10162
10163   if (version)
10164     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10165
10166   if (traffic_class)
10167     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10168
10169   if (flow_label)
10170     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10171
10172   ip->ip_version_traffic_class_and_flow_label =
10173     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10174
10175   *maskp = mask;
10176   return 1;
10177 }
10178
10179 uword
10180 unformat_l3_mask (unformat_input_t * input, va_list * args)
10181 {
10182   u8 **maskp = va_arg (*args, u8 **);
10183
10184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10185     {
10186       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10187         return 1;
10188       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10189         return 1;
10190       else
10191         break;
10192     }
10193   return 0;
10194 }
10195
10196 uword
10197 unformat_l2_mask (unformat_input_t * input, va_list * args)
10198 {
10199   u8 **maskp = va_arg (*args, u8 **);
10200   u8 *mask = 0;
10201   u8 src = 0;
10202   u8 dst = 0;
10203   u8 proto = 0;
10204   u8 tag1 = 0;
10205   u8 tag2 = 0;
10206   u8 ignore_tag1 = 0;
10207   u8 ignore_tag2 = 0;
10208   u8 cos1 = 0;
10209   u8 cos2 = 0;
10210   u8 dot1q = 0;
10211   u8 dot1ad = 0;
10212   int len = 14;
10213
10214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (input, "src"))
10217         src = 1;
10218       else if (unformat (input, "dst"))
10219         dst = 1;
10220       else if (unformat (input, "proto"))
10221         proto = 1;
10222       else if (unformat (input, "tag1"))
10223         tag1 = 1;
10224       else if (unformat (input, "tag2"))
10225         tag2 = 1;
10226       else if (unformat (input, "ignore-tag1"))
10227         ignore_tag1 = 1;
10228       else if (unformat (input, "ignore-tag2"))
10229         ignore_tag2 = 1;
10230       else if (unformat (input, "cos1"))
10231         cos1 = 1;
10232       else if (unformat (input, "cos2"))
10233         cos2 = 1;
10234       else if (unformat (input, "dot1q"))
10235         dot1q = 1;
10236       else if (unformat (input, "dot1ad"))
10237         dot1ad = 1;
10238       else
10239         break;
10240     }
10241   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10242        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10243     return 0;
10244
10245   if (tag1 || ignore_tag1 || cos1 || dot1q)
10246     len = 18;
10247   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10248     len = 22;
10249
10250   vec_validate (mask, len - 1);
10251
10252   if (dst)
10253     memset (mask, 0xff, 6);
10254
10255   if (src)
10256     memset (mask + 6, 0xff, 6);
10257
10258   if (tag2 || dot1ad)
10259     {
10260       /* inner vlan tag */
10261       if (tag2)
10262         {
10263           mask[19] = 0xff;
10264           mask[18] = 0x0f;
10265         }
10266       if (cos2)
10267         mask[18] |= 0xe0;
10268       if (proto)
10269         mask[21] = mask[20] = 0xff;
10270       if (tag1)
10271         {
10272           mask[15] = 0xff;
10273           mask[14] = 0x0f;
10274         }
10275       if (cos1)
10276         mask[14] |= 0xe0;
10277       *maskp = mask;
10278       return 1;
10279     }
10280   if (tag1 | dot1q)
10281     {
10282       if (tag1)
10283         {
10284           mask[15] = 0xff;
10285           mask[14] = 0x0f;
10286         }
10287       if (cos1)
10288         mask[14] |= 0xe0;
10289       if (proto)
10290         mask[16] = mask[17] = 0xff;
10291
10292       *maskp = mask;
10293       return 1;
10294     }
10295   if (cos2)
10296     mask[18] |= 0xe0;
10297   if (cos1)
10298     mask[14] |= 0xe0;
10299   if (proto)
10300     mask[12] = mask[13] = 0xff;
10301
10302   *maskp = mask;
10303   return 1;
10304 }
10305
10306 uword
10307 unformat_classify_mask (unformat_input_t * input, va_list * args)
10308 {
10309   u8 **maskp = va_arg (*args, u8 **);
10310   u32 *skipp = va_arg (*args, u32 *);
10311   u32 *matchp = va_arg (*args, u32 *);
10312   u32 match;
10313   u8 *mask = 0;
10314   u8 *l2 = 0;
10315   u8 *l3 = 0;
10316   u8 *l4 = 0;
10317   int i;
10318
10319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10320     {
10321       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10322         ;
10323       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10324         ;
10325       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10326         ;
10327       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10328         ;
10329       else
10330         break;
10331     }
10332
10333   if (l4 && !l3)
10334     {
10335       vec_free (mask);
10336       vec_free (l2);
10337       vec_free (l4);
10338       return 0;
10339     }
10340
10341   if (mask || l2 || l3 || l4)
10342     {
10343       if (l2 || l3 || l4)
10344         {
10345           /* "With a free Ethernet header in every package" */
10346           if (l2 == 0)
10347             vec_validate (l2, 13);
10348           mask = l2;
10349           if (vec_len (l3))
10350             {
10351               vec_append (mask, l3);
10352               vec_free (l3);
10353             }
10354           if (vec_len (l4))
10355             {
10356               vec_append (mask, l4);
10357               vec_free (l4);
10358             }
10359         }
10360
10361       /* Scan forward looking for the first significant mask octet */
10362       for (i = 0; i < vec_len (mask); i++)
10363         if (mask[i])
10364           break;
10365
10366       /* compute (skip, match) params */
10367       *skipp = i / sizeof (u32x4);
10368       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10369
10370       /* Pad mask to an even multiple of the vector size */
10371       while (vec_len (mask) % sizeof (u32x4))
10372         vec_add1 (mask, 0);
10373
10374       match = vec_len (mask) / sizeof (u32x4);
10375
10376       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10377         {
10378           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10379           if (*tmp || *(tmp + 1))
10380             break;
10381           match--;
10382         }
10383       if (match == 0)
10384         clib_warning ("BUG: match 0");
10385
10386       _vec_len (mask) = match * sizeof (u32x4);
10387
10388       *matchp = match;
10389       *maskp = mask;
10390
10391       return 1;
10392     }
10393
10394   return 0;
10395 }
10396 #endif /* VPP_API_TEST_BUILTIN */
10397
10398 #define foreach_l2_next                         \
10399 _(drop, DROP)                                   \
10400 _(ethernet, ETHERNET_INPUT)                     \
10401 _(ip4, IP4_INPUT)                               \
10402 _(ip6, IP6_INPUT)
10403
10404 uword
10405 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10406 {
10407   u32 *miss_next_indexp = va_arg (*args, u32 *);
10408   u32 next_index = 0;
10409   u32 tmp;
10410
10411 #define _(n,N) \
10412   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10413   foreach_l2_next;
10414 #undef _
10415
10416   if (unformat (input, "%d", &tmp))
10417     {
10418       next_index = tmp;
10419       goto out;
10420     }
10421
10422   return 0;
10423
10424 out:
10425   *miss_next_indexp = next_index;
10426   return 1;
10427 }
10428
10429 #define foreach_ip_next                         \
10430 _(drop, DROP)                                   \
10431 _(local, LOCAL)                                 \
10432 _(rewrite, REWRITE)
10433
10434 uword
10435 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10436 {
10437   u32 *miss_next_indexp = va_arg (*args, u32 *);
10438   u32 next_index = 0;
10439   u32 tmp;
10440
10441 #define _(n,N) \
10442   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10443   foreach_ip_next;
10444 #undef _
10445
10446   if (unformat (input, "%d", &tmp))
10447     {
10448       next_index = tmp;
10449       goto out;
10450     }
10451
10452   return 0;
10453
10454 out:
10455   *miss_next_indexp = next_index;
10456   return 1;
10457 }
10458
10459 #define foreach_acl_next                        \
10460 _(deny, DENY)
10461
10462 uword
10463 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10464 {
10465   u32 *miss_next_indexp = va_arg (*args, u32 *);
10466   u32 next_index = 0;
10467   u32 tmp;
10468
10469 #define _(n,N) \
10470   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10471   foreach_acl_next;
10472 #undef _
10473
10474   if (unformat (input, "permit"))
10475     {
10476       next_index = ~0;
10477       goto out;
10478     }
10479   else if (unformat (input, "%d", &tmp))
10480     {
10481       next_index = tmp;
10482       goto out;
10483     }
10484
10485   return 0;
10486
10487 out:
10488   *miss_next_indexp = next_index;
10489   return 1;
10490 }
10491
10492 uword
10493 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10494 {
10495   u32 *r = va_arg (*args, u32 *);
10496
10497   if (unformat (input, "conform-color"))
10498     *r = POLICE_CONFORM;
10499   else if (unformat (input, "exceed-color"))
10500     *r = POLICE_EXCEED;
10501   else
10502     return 0;
10503
10504   return 1;
10505 }
10506
10507 static int
10508 api_classify_add_del_table (vat_main_t * vam)
10509 {
10510   unformat_input_t *i = vam->input;
10511   vl_api_classify_add_del_table_t *mp;
10512
10513   u32 nbuckets = 2;
10514   u32 skip = ~0;
10515   u32 match = ~0;
10516   int is_add = 1;
10517   int del_chain = 0;
10518   u32 table_index = ~0;
10519   u32 next_table_index = ~0;
10520   u32 miss_next_index = ~0;
10521   u32 memory_size = 32 << 20;
10522   u8 *mask = 0;
10523   u32 current_data_flag = 0;
10524   int current_data_offset = 0;
10525   int ret;
10526
10527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10528     {
10529       if (unformat (i, "del"))
10530         is_add = 0;
10531       else if (unformat (i, "del-chain"))
10532         {
10533           is_add = 0;
10534           del_chain = 1;
10535         }
10536       else if (unformat (i, "buckets %d", &nbuckets))
10537         ;
10538       else if (unformat (i, "memory_size %d", &memory_size))
10539         ;
10540       else if (unformat (i, "skip %d", &skip))
10541         ;
10542       else if (unformat (i, "match %d", &match))
10543         ;
10544       else if (unformat (i, "table %d", &table_index))
10545         ;
10546       else if (unformat (i, "mask %U", unformat_classify_mask,
10547                          &mask, &skip, &match))
10548         ;
10549       else if (unformat (i, "next-table %d", &next_table_index))
10550         ;
10551       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10552                          &miss_next_index))
10553         ;
10554       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10555                          &miss_next_index))
10556         ;
10557       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10558                          &miss_next_index))
10559         ;
10560       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10561         ;
10562       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10563         ;
10564       else
10565         break;
10566     }
10567
10568   if (is_add && mask == 0)
10569     {
10570       errmsg ("Mask required");
10571       return -99;
10572     }
10573
10574   if (is_add && skip == ~0)
10575     {
10576       errmsg ("skip count required");
10577       return -99;
10578     }
10579
10580   if (is_add && match == ~0)
10581     {
10582       errmsg ("match count required");
10583       return -99;
10584     }
10585
10586   if (!is_add && table_index == ~0)
10587     {
10588       errmsg ("table index required for delete");
10589       return -99;
10590     }
10591
10592   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10593
10594   mp->is_add = is_add;
10595   mp->del_chain = del_chain;
10596   mp->table_index = ntohl (table_index);
10597   mp->nbuckets = ntohl (nbuckets);
10598   mp->memory_size = ntohl (memory_size);
10599   mp->skip_n_vectors = ntohl (skip);
10600   mp->match_n_vectors = ntohl (match);
10601   mp->next_table_index = ntohl (next_table_index);
10602   mp->miss_next_index = ntohl (miss_next_index);
10603   mp->current_data_flag = ntohl (current_data_flag);
10604   mp->current_data_offset = ntohl (current_data_offset);
10605   clib_memcpy (mp->mask, mask, vec_len (mask));
10606
10607   vec_free (mask);
10608
10609   S (mp);
10610   W (ret);
10611   return ret;
10612 }
10613
10614 #if VPP_API_TEST_BUILTIN == 0
10615 uword
10616 unformat_l4_match (unformat_input_t * input, va_list * args)
10617 {
10618   u8 **matchp = va_arg (*args, u8 **);
10619
10620   u8 *proto_header = 0;
10621   int src_port = 0;
10622   int dst_port = 0;
10623
10624   tcpudp_header_t h;
10625
10626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10627     {
10628       if (unformat (input, "src_port %d", &src_port))
10629         ;
10630       else if (unformat (input, "dst_port %d", &dst_port))
10631         ;
10632       else
10633         return 0;
10634     }
10635
10636   h.src_port = clib_host_to_net_u16 (src_port);
10637   h.dst_port = clib_host_to_net_u16 (dst_port);
10638   vec_validate (proto_header, sizeof (h) - 1);
10639   memcpy (proto_header, &h, sizeof (h));
10640
10641   *matchp = proto_header;
10642
10643   return 1;
10644 }
10645
10646 uword
10647 unformat_ip4_match (unformat_input_t * input, va_list * args)
10648 {
10649   u8 **matchp = va_arg (*args, u8 **);
10650   u8 *match = 0;
10651   ip4_header_t *ip;
10652   int version = 0;
10653   u32 version_val;
10654   int hdr_length = 0;
10655   u32 hdr_length_val;
10656   int src = 0, dst = 0;
10657   ip4_address_t src_val, dst_val;
10658   int proto = 0;
10659   u32 proto_val;
10660   int tos = 0;
10661   u32 tos_val;
10662   int length = 0;
10663   u32 length_val;
10664   int fragment_id = 0;
10665   u32 fragment_id_val;
10666   int ttl = 0;
10667   int ttl_val;
10668   int checksum = 0;
10669   u32 checksum_val;
10670
10671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10672     {
10673       if (unformat (input, "version %d", &version_val))
10674         version = 1;
10675       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10676         hdr_length = 1;
10677       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10678         src = 1;
10679       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10680         dst = 1;
10681       else if (unformat (input, "proto %d", &proto_val))
10682         proto = 1;
10683       else if (unformat (input, "tos %d", &tos_val))
10684         tos = 1;
10685       else if (unformat (input, "length %d", &length_val))
10686         length = 1;
10687       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10688         fragment_id = 1;
10689       else if (unformat (input, "ttl %d", &ttl_val))
10690         ttl = 1;
10691       else if (unformat (input, "checksum %d", &checksum_val))
10692         checksum = 1;
10693       else
10694         break;
10695     }
10696
10697   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10698       + ttl + checksum == 0)
10699     return 0;
10700
10701   /*
10702    * Aligned because we use the real comparison functions
10703    */
10704   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10705
10706   ip = (ip4_header_t *) match;
10707
10708   /* These are realistically matched in practice */
10709   if (src)
10710     ip->src_address.as_u32 = src_val.as_u32;
10711
10712   if (dst)
10713     ip->dst_address.as_u32 = dst_val.as_u32;
10714
10715   if (proto)
10716     ip->protocol = proto_val;
10717
10718
10719   /* These are not, but they're included for completeness */
10720   if (version)
10721     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10722
10723   if (hdr_length)
10724     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10725
10726   if (tos)
10727     ip->tos = tos_val;
10728
10729   if (length)
10730     ip->length = clib_host_to_net_u16 (length_val);
10731
10732   if (ttl)
10733     ip->ttl = ttl_val;
10734
10735   if (checksum)
10736     ip->checksum = clib_host_to_net_u16 (checksum_val);
10737
10738   *matchp = match;
10739   return 1;
10740 }
10741
10742 uword
10743 unformat_ip6_match (unformat_input_t * input, va_list * args)
10744 {
10745   u8 **matchp = va_arg (*args, u8 **);
10746   u8 *match = 0;
10747   ip6_header_t *ip;
10748   int version = 0;
10749   u32 version_val;
10750   u8 traffic_class = 0;
10751   u32 traffic_class_val = 0;
10752   u8 flow_label = 0;
10753   u8 flow_label_val;
10754   int src = 0, dst = 0;
10755   ip6_address_t src_val, dst_val;
10756   int proto = 0;
10757   u32 proto_val;
10758   int payload_length = 0;
10759   u32 payload_length_val;
10760   int hop_limit = 0;
10761   int hop_limit_val;
10762   u32 ip_version_traffic_class_and_flow_label;
10763
10764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (unformat (input, "version %d", &version_val))
10767         version = 1;
10768       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10769         traffic_class = 1;
10770       else if (unformat (input, "flow_label %d", &flow_label_val))
10771         flow_label = 1;
10772       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10773         src = 1;
10774       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10775         dst = 1;
10776       else if (unformat (input, "proto %d", &proto_val))
10777         proto = 1;
10778       else if (unformat (input, "payload_length %d", &payload_length_val))
10779         payload_length = 1;
10780       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10781         hop_limit = 1;
10782       else
10783         break;
10784     }
10785
10786   if (version + traffic_class + flow_label + src + dst + proto +
10787       payload_length + hop_limit == 0)
10788     return 0;
10789
10790   /*
10791    * Aligned because we use the real comparison functions
10792    */
10793   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10794
10795   ip = (ip6_header_t *) match;
10796
10797   if (src)
10798     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10799
10800   if (dst)
10801     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10802
10803   if (proto)
10804     ip->protocol = proto_val;
10805
10806   ip_version_traffic_class_and_flow_label = 0;
10807
10808   if (version)
10809     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10810
10811   if (traffic_class)
10812     ip_version_traffic_class_and_flow_label |=
10813       (traffic_class_val & 0xFF) << 20;
10814
10815   if (flow_label)
10816     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10817
10818   ip->ip_version_traffic_class_and_flow_label =
10819     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10820
10821   if (payload_length)
10822     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10823
10824   if (hop_limit)
10825     ip->hop_limit = hop_limit_val;
10826
10827   *matchp = match;
10828   return 1;
10829 }
10830
10831 uword
10832 unformat_l3_match (unformat_input_t * input, va_list * args)
10833 {
10834   u8 **matchp = va_arg (*args, u8 **);
10835
10836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10839         return 1;
10840       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10841         return 1;
10842       else
10843         break;
10844     }
10845   return 0;
10846 }
10847
10848 uword
10849 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10850 {
10851   u8 *tagp = va_arg (*args, u8 *);
10852   u32 tag;
10853
10854   if (unformat (input, "%d", &tag))
10855     {
10856       tagp[0] = (tag >> 8) & 0x0F;
10857       tagp[1] = tag & 0xFF;
10858       return 1;
10859     }
10860
10861   return 0;
10862 }
10863
10864 uword
10865 unformat_l2_match (unformat_input_t * input, va_list * args)
10866 {
10867   u8 **matchp = va_arg (*args, u8 **);
10868   u8 *match = 0;
10869   u8 src = 0;
10870   u8 src_val[6];
10871   u8 dst = 0;
10872   u8 dst_val[6];
10873   u8 proto = 0;
10874   u16 proto_val;
10875   u8 tag1 = 0;
10876   u8 tag1_val[2];
10877   u8 tag2 = 0;
10878   u8 tag2_val[2];
10879   int len = 14;
10880   u8 ignore_tag1 = 0;
10881   u8 ignore_tag2 = 0;
10882   u8 cos1 = 0;
10883   u8 cos2 = 0;
10884   u32 cos1_val = 0;
10885   u32 cos2_val = 0;
10886
10887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10888     {
10889       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10890         src = 1;
10891       else
10892         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10893         dst = 1;
10894       else if (unformat (input, "proto %U",
10895                          unformat_ethernet_type_host_byte_order, &proto_val))
10896         proto = 1;
10897       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10898         tag1 = 1;
10899       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10900         tag2 = 1;
10901       else if (unformat (input, "ignore-tag1"))
10902         ignore_tag1 = 1;
10903       else if (unformat (input, "ignore-tag2"))
10904         ignore_tag2 = 1;
10905       else if (unformat (input, "cos1 %d", &cos1_val))
10906         cos1 = 1;
10907       else if (unformat (input, "cos2 %d", &cos2_val))
10908         cos2 = 1;
10909       else
10910         break;
10911     }
10912   if ((src + dst + proto + tag1 + tag2 +
10913        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10914     return 0;
10915
10916   if (tag1 || ignore_tag1 || cos1)
10917     len = 18;
10918   if (tag2 || ignore_tag2 || cos2)
10919     len = 22;
10920
10921   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10922
10923   if (dst)
10924     clib_memcpy (match, dst_val, 6);
10925
10926   if (src)
10927     clib_memcpy (match + 6, src_val, 6);
10928
10929   if (tag2)
10930     {
10931       /* inner vlan tag */
10932       match[19] = tag2_val[1];
10933       match[18] = tag2_val[0];
10934       if (cos2)
10935         match[18] |= (cos2_val & 0x7) << 5;
10936       if (proto)
10937         {
10938           match[21] = proto_val & 0xff;
10939           match[20] = proto_val >> 8;
10940         }
10941       if (tag1)
10942         {
10943           match[15] = tag1_val[1];
10944           match[14] = tag1_val[0];
10945         }
10946       if (cos1)
10947         match[14] |= (cos1_val & 0x7) << 5;
10948       *matchp = match;
10949       return 1;
10950     }
10951   if (tag1)
10952     {
10953       match[15] = tag1_val[1];
10954       match[14] = tag1_val[0];
10955       if (proto)
10956         {
10957           match[17] = proto_val & 0xff;
10958           match[16] = proto_val >> 8;
10959         }
10960       if (cos1)
10961         match[14] |= (cos1_val & 0x7) << 5;
10962
10963       *matchp = match;
10964       return 1;
10965     }
10966   if (cos2)
10967     match[18] |= (cos2_val & 0x7) << 5;
10968   if (cos1)
10969     match[14] |= (cos1_val & 0x7) << 5;
10970   if (proto)
10971     {
10972       match[13] = proto_val & 0xff;
10973       match[12] = proto_val >> 8;
10974     }
10975
10976   *matchp = match;
10977   return 1;
10978 }
10979 #endif
10980
10981 uword
10982 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10983 {
10984   u8 **matchp = va_arg (*args, u8 **);
10985   u32 skip_n_vectors = va_arg (*args, u32);
10986   u32 match_n_vectors = va_arg (*args, u32);
10987
10988   u8 *match = 0;
10989   u8 *l2 = 0;
10990   u8 *l3 = 0;
10991   u8 *l4 = 0;
10992
10993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10994     {
10995       if (unformat (input, "hex %U", unformat_hex_string, &match))
10996         ;
10997       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10998         ;
10999       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11000         ;
11001       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11002         ;
11003       else
11004         break;
11005     }
11006
11007   if (l4 && !l3)
11008     {
11009       vec_free (match);
11010       vec_free (l2);
11011       vec_free (l4);
11012       return 0;
11013     }
11014
11015   if (match || l2 || l3 || l4)
11016     {
11017       if (l2 || l3 || l4)
11018         {
11019           /* "Win a free Ethernet header in every packet" */
11020           if (l2 == 0)
11021             vec_validate_aligned (l2, 13, sizeof (u32x4));
11022           match = l2;
11023           if (vec_len (l3))
11024             {
11025               vec_append_aligned (match, l3, sizeof (u32x4));
11026               vec_free (l3);
11027             }
11028           if (vec_len (l4))
11029             {
11030               vec_append_aligned (match, l4, sizeof (u32x4));
11031               vec_free (l4);
11032             }
11033         }
11034
11035       /* Make sure the vector is big enough even if key is all 0's */
11036       vec_validate_aligned
11037         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11038          sizeof (u32x4));
11039
11040       /* Set size, include skipped vectors */
11041       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11042
11043       *matchp = match;
11044
11045       return 1;
11046     }
11047
11048   return 0;
11049 }
11050
11051 static int
11052 api_classify_add_del_session (vat_main_t * vam)
11053 {
11054   unformat_input_t *i = vam->input;
11055   vl_api_classify_add_del_session_t *mp;
11056   int is_add = 1;
11057   u32 table_index = ~0;
11058   u32 hit_next_index = ~0;
11059   u32 opaque_index = ~0;
11060   u8 *match = 0;
11061   i32 advance = 0;
11062   u32 skip_n_vectors = 0;
11063   u32 match_n_vectors = 0;
11064   u32 action = 0;
11065   u32 metadata = 0;
11066   int ret;
11067
11068   /*
11069    * Warning: you have to supply skip_n and match_n
11070    * because the API client cant simply look at the classify
11071    * table object.
11072    */
11073
11074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11075     {
11076       if (unformat (i, "del"))
11077         is_add = 0;
11078       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11079                          &hit_next_index))
11080         ;
11081       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11082                          &hit_next_index))
11083         ;
11084       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11085                          &hit_next_index))
11086         ;
11087       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11088         ;
11089       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11090         ;
11091       else if (unformat (i, "opaque-index %d", &opaque_index))
11092         ;
11093       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11094         ;
11095       else if (unformat (i, "match_n %d", &match_n_vectors))
11096         ;
11097       else if (unformat (i, "match %U", api_unformat_classify_match,
11098                          &match, skip_n_vectors, match_n_vectors))
11099         ;
11100       else if (unformat (i, "advance %d", &advance))
11101         ;
11102       else if (unformat (i, "table-index %d", &table_index))
11103         ;
11104       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11105         action = 1;
11106       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11107         action = 2;
11108       else if (unformat (i, "action %d", &action))
11109         ;
11110       else if (unformat (i, "metadata %d", &metadata))
11111         ;
11112       else
11113         break;
11114     }
11115
11116   if (table_index == ~0)
11117     {
11118       errmsg ("Table index required");
11119       return -99;
11120     }
11121
11122   if (is_add && match == 0)
11123     {
11124       errmsg ("Match value required");
11125       return -99;
11126     }
11127
11128   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11129
11130   mp->is_add = is_add;
11131   mp->table_index = ntohl (table_index);
11132   mp->hit_next_index = ntohl (hit_next_index);
11133   mp->opaque_index = ntohl (opaque_index);
11134   mp->advance = ntohl (advance);
11135   mp->action = action;
11136   mp->metadata = ntohl (metadata);
11137   clib_memcpy (mp->match, match, vec_len (match));
11138   vec_free (match);
11139
11140   S (mp);
11141   W (ret);
11142   return ret;
11143 }
11144
11145 static int
11146 api_classify_set_interface_ip_table (vat_main_t * vam)
11147 {
11148   unformat_input_t *i = vam->input;
11149   vl_api_classify_set_interface_ip_table_t *mp;
11150   u32 sw_if_index;
11151   int sw_if_index_set;
11152   u32 table_index = ~0;
11153   u8 is_ipv6 = 0;
11154   int ret;
11155
11156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11157     {
11158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11159         sw_if_index_set = 1;
11160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11161         sw_if_index_set = 1;
11162       else if (unformat (i, "table %d", &table_index))
11163         ;
11164       else
11165         {
11166           clib_warning ("parse error '%U'", format_unformat_error, i);
11167           return -99;
11168         }
11169     }
11170
11171   if (sw_if_index_set == 0)
11172     {
11173       errmsg ("missing interface name or sw_if_index");
11174       return -99;
11175     }
11176
11177
11178   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11179
11180   mp->sw_if_index = ntohl (sw_if_index);
11181   mp->table_index = ntohl (table_index);
11182   mp->is_ipv6 = is_ipv6;
11183
11184   S (mp);
11185   W (ret);
11186   return ret;
11187 }
11188
11189 static int
11190 api_classify_set_interface_l2_tables (vat_main_t * vam)
11191 {
11192   unformat_input_t *i = vam->input;
11193   vl_api_classify_set_interface_l2_tables_t *mp;
11194   u32 sw_if_index;
11195   int sw_if_index_set;
11196   u32 ip4_table_index = ~0;
11197   u32 ip6_table_index = ~0;
11198   u32 other_table_index = ~0;
11199   u32 is_input = 1;
11200   int ret;
11201
11202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11205         sw_if_index_set = 1;
11206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11207         sw_if_index_set = 1;
11208       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11209         ;
11210       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11211         ;
11212       else if (unformat (i, "other-table %d", &other_table_index))
11213         ;
11214       else if (unformat (i, "is-input %d", &is_input))
11215         ;
11216       else
11217         {
11218           clib_warning ("parse error '%U'", format_unformat_error, i);
11219           return -99;
11220         }
11221     }
11222
11223   if (sw_if_index_set == 0)
11224     {
11225       errmsg ("missing interface name or sw_if_index");
11226       return -99;
11227     }
11228
11229
11230   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11231
11232   mp->sw_if_index = ntohl (sw_if_index);
11233   mp->ip4_table_index = ntohl (ip4_table_index);
11234   mp->ip6_table_index = ntohl (ip6_table_index);
11235   mp->other_table_index = ntohl (other_table_index);
11236   mp->is_input = (u8) is_input;
11237
11238   S (mp);
11239   W (ret);
11240   return ret;
11241 }
11242
11243 static int
11244 api_set_ipfix_exporter (vat_main_t * vam)
11245 {
11246   unformat_input_t *i = vam->input;
11247   vl_api_set_ipfix_exporter_t *mp;
11248   ip4_address_t collector_address;
11249   u8 collector_address_set = 0;
11250   u32 collector_port = ~0;
11251   ip4_address_t src_address;
11252   u8 src_address_set = 0;
11253   u32 vrf_id = ~0;
11254   u32 path_mtu = ~0;
11255   u32 template_interval = ~0;
11256   u8 udp_checksum = 0;
11257   int ret;
11258
11259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11260     {
11261       if (unformat (i, "collector_address %U", unformat_ip4_address,
11262                     &collector_address))
11263         collector_address_set = 1;
11264       else if (unformat (i, "collector_port %d", &collector_port))
11265         ;
11266       else if (unformat (i, "src_address %U", unformat_ip4_address,
11267                          &src_address))
11268         src_address_set = 1;
11269       else if (unformat (i, "vrf_id %d", &vrf_id))
11270         ;
11271       else if (unformat (i, "path_mtu %d", &path_mtu))
11272         ;
11273       else if (unformat (i, "template_interval %d", &template_interval))
11274         ;
11275       else if (unformat (i, "udp_checksum"))
11276         udp_checksum = 1;
11277       else
11278         break;
11279     }
11280
11281   if (collector_address_set == 0)
11282     {
11283       errmsg ("collector_address required");
11284       return -99;
11285     }
11286
11287   if (src_address_set == 0)
11288     {
11289       errmsg ("src_address required");
11290       return -99;
11291     }
11292
11293   M (SET_IPFIX_EXPORTER, mp);
11294
11295   memcpy (mp->collector_address, collector_address.data,
11296           sizeof (collector_address.data));
11297   mp->collector_port = htons ((u16) collector_port);
11298   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11299   mp->vrf_id = htonl (vrf_id);
11300   mp->path_mtu = htonl (path_mtu);
11301   mp->template_interval = htonl (template_interval);
11302   mp->udp_checksum = udp_checksum;
11303
11304   S (mp);
11305   W (ret);
11306   return ret;
11307 }
11308
11309 static int
11310 api_set_ipfix_classify_stream (vat_main_t * vam)
11311 {
11312   unformat_input_t *i = vam->input;
11313   vl_api_set_ipfix_classify_stream_t *mp;
11314   u32 domain_id = 0;
11315   u32 src_port = UDP_DST_PORT_ipfix;
11316   int ret;
11317
11318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11319     {
11320       if (unformat (i, "domain %d", &domain_id))
11321         ;
11322       else if (unformat (i, "src_port %d", &src_port))
11323         ;
11324       else
11325         {
11326           errmsg ("unknown input `%U'", format_unformat_error, i);
11327           return -99;
11328         }
11329     }
11330
11331   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11332
11333   mp->domain_id = htonl (domain_id);
11334   mp->src_port = htons ((u16) src_port);
11335
11336   S (mp);
11337   W (ret);
11338   return ret;
11339 }
11340
11341 static int
11342 api_ipfix_classify_table_add_del (vat_main_t * vam)
11343 {
11344   unformat_input_t *i = vam->input;
11345   vl_api_ipfix_classify_table_add_del_t *mp;
11346   int is_add = -1;
11347   u32 classify_table_index = ~0;
11348   u8 ip_version = 0;
11349   u8 transport_protocol = 255;
11350   int ret;
11351
11352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11353     {
11354       if (unformat (i, "add"))
11355         is_add = 1;
11356       else if (unformat (i, "del"))
11357         is_add = 0;
11358       else if (unformat (i, "table %d", &classify_table_index))
11359         ;
11360       else if (unformat (i, "ip4"))
11361         ip_version = 4;
11362       else if (unformat (i, "ip6"))
11363         ip_version = 6;
11364       else if (unformat (i, "tcp"))
11365         transport_protocol = 6;
11366       else if (unformat (i, "udp"))
11367         transport_protocol = 17;
11368       else
11369         {
11370           errmsg ("unknown input `%U'", format_unformat_error, i);
11371           return -99;
11372         }
11373     }
11374
11375   if (is_add == -1)
11376     {
11377       errmsg ("expecting: add|del");
11378       return -99;
11379     }
11380   if (classify_table_index == ~0)
11381     {
11382       errmsg ("classifier table not specified");
11383       return -99;
11384     }
11385   if (ip_version == 0)
11386     {
11387       errmsg ("IP version not specified");
11388       return -99;
11389     }
11390
11391   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11392
11393   mp->is_add = is_add;
11394   mp->table_id = htonl (classify_table_index);
11395   mp->ip_version = ip_version;
11396   mp->transport_protocol = transport_protocol;
11397
11398   S (mp);
11399   W (ret);
11400   return ret;
11401 }
11402
11403 static int
11404 api_get_node_index (vat_main_t * vam)
11405 {
11406   unformat_input_t *i = vam->input;
11407   vl_api_get_node_index_t *mp;
11408   u8 *name = 0;
11409   int ret;
11410
11411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11412     {
11413       if (unformat (i, "node %s", &name))
11414         ;
11415       else
11416         break;
11417     }
11418   if (name == 0)
11419     {
11420       errmsg ("node name required");
11421       return -99;
11422     }
11423   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11424     {
11425       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11426       return -99;
11427     }
11428
11429   M (GET_NODE_INDEX, mp);
11430   clib_memcpy (mp->node_name, name, vec_len (name));
11431   vec_free (name);
11432
11433   S (mp);
11434   W (ret);
11435   return ret;
11436 }
11437
11438 static int
11439 api_get_next_index (vat_main_t * vam)
11440 {
11441   unformat_input_t *i = vam->input;
11442   vl_api_get_next_index_t *mp;
11443   u8 *node_name = 0, *next_node_name = 0;
11444   int ret;
11445
11446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11447     {
11448       if (unformat (i, "node-name %s", &node_name))
11449         ;
11450       else if (unformat (i, "next-node-name %s", &next_node_name))
11451         break;
11452     }
11453
11454   if (node_name == 0)
11455     {
11456       errmsg ("node name required");
11457       return -99;
11458     }
11459   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11460     {
11461       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11462       return -99;
11463     }
11464
11465   if (next_node_name == 0)
11466     {
11467       errmsg ("next node name required");
11468       return -99;
11469     }
11470   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11471     {
11472       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11473       return -99;
11474     }
11475
11476   M (GET_NEXT_INDEX, mp);
11477   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11478   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11479   vec_free (node_name);
11480   vec_free (next_node_name);
11481
11482   S (mp);
11483   W (ret);
11484   return ret;
11485 }
11486
11487 static int
11488 api_add_node_next (vat_main_t * vam)
11489 {
11490   unformat_input_t *i = vam->input;
11491   vl_api_add_node_next_t *mp;
11492   u8 *name = 0;
11493   u8 *next = 0;
11494   int ret;
11495
11496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11497     {
11498       if (unformat (i, "node %s", &name))
11499         ;
11500       else if (unformat (i, "next %s", &next))
11501         ;
11502       else
11503         break;
11504     }
11505   if (name == 0)
11506     {
11507       errmsg ("node name required");
11508       return -99;
11509     }
11510   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11511     {
11512       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11513       return -99;
11514     }
11515   if (next == 0)
11516     {
11517       errmsg ("next node required");
11518       return -99;
11519     }
11520   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11521     {
11522       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11523       return -99;
11524     }
11525
11526   M (ADD_NODE_NEXT, mp);
11527   clib_memcpy (mp->node_name, name, vec_len (name));
11528   clib_memcpy (mp->next_name, next, vec_len (next));
11529   vec_free (name);
11530   vec_free (next);
11531
11532   S (mp);
11533   W (ret);
11534   return ret;
11535 }
11536
11537 static int
11538 api_l2tpv3_create_tunnel (vat_main_t * vam)
11539 {
11540   unformat_input_t *i = vam->input;
11541   ip6_address_t client_address, our_address;
11542   int client_address_set = 0;
11543   int our_address_set = 0;
11544   u32 local_session_id = 0;
11545   u32 remote_session_id = 0;
11546   u64 local_cookie = 0;
11547   u64 remote_cookie = 0;
11548   u8 l2_sublayer_present = 0;
11549   vl_api_l2tpv3_create_tunnel_t *mp;
11550   int ret;
11551
11552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11553     {
11554       if (unformat (i, "client_address %U", unformat_ip6_address,
11555                     &client_address))
11556         client_address_set = 1;
11557       else if (unformat (i, "our_address %U", unformat_ip6_address,
11558                          &our_address))
11559         our_address_set = 1;
11560       else if (unformat (i, "local_session_id %d", &local_session_id))
11561         ;
11562       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11563         ;
11564       else if (unformat (i, "local_cookie %lld", &local_cookie))
11565         ;
11566       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11567         ;
11568       else if (unformat (i, "l2-sublayer-present"))
11569         l2_sublayer_present = 1;
11570       else
11571         break;
11572     }
11573
11574   if (client_address_set == 0)
11575     {
11576       errmsg ("client_address required");
11577       return -99;
11578     }
11579
11580   if (our_address_set == 0)
11581     {
11582       errmsg ("our_address required");
11583       return -99;
11584     }
11585
11586   M (L2TPV3_CREATE_TUNNEL, mp);
11587
11588   clib_memcpy (mp->client_address, client_address.as_u8,
11589                sizeof (mp->client_address));
11590
11591   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11592
11593   mp->local_session_id = ntohl (local_session_id);
11594   mp->remote_session_id = ntohl (remote_session_id);
11595   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11596   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11597   mp->l2_sublayer_present = l2_sublayer_present;
11598   mp->is_ipv6 = 1;
11599
11600   S (mp);
11601   W (ret);
11602   return ret;
11603 }
11604
11605 static int
11606 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11607 {
11608   unformat_input_t *i = vam->input;
11609   u32 sw_if_index;
11610   u8 sw_if_index_set = 0;
11611   u64 new_local_cookie = 0;
11612   u64 new_remote_cookie = 0;
11613   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11614   int ret;
11615
11616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11617     {
11618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11619         sw_if_index_set = 1;
11620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11621         sw_if_index_set = 1;
11622       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11623         ;
11624       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11625         ;
11626       else
11627         break;
11628     }
11629
11630   if (sw_if_index_set == 0)
11631     {
11632       errmsg ("missing interface name or sw_if_index");
11633       return -99;
11634     }
11635
11636   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11637
11638   mp->sw_if_index = ntohl (sw_if_index);
11639   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11640   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11641
11642   S (mp);
11643   W (ret);
11644   return ret;
11645 }
11646
11647 static int
11648 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11649 {
11650   unformat_input_t *i = vam->input;
11651   vl_api_l2tpv3_interface_enable_disable_t *mp;
11652   u32 sw_if_index;
11653   u8 sw_if_index_set = 0;
11654   u8 enable_disable = 1;
11655   int ret;
11656
11657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11658     {
11659       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11660         sw_if_index_set = 1;
11661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11662         sw_if_index_set = 1;
11663       else if (unformat (i, "enable"))
11664         enable_disable = 1;
11665       else if (unformat (i, "disable"))
11666         enable_disable = 0;
11667       else
11668         break;
11669     }
11670
11671   if (sw_if_index_set == 0)
11672     {
11673       errmsg ("missing interface name or sw_if_index");
11674       return -99;
11675     }
11676
11677   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11678
11679   mp->sw_if_index = ntohl (sw_if_index);
11680   mp->enable_disable = enable_disable;
11681
11682   S (mp);
11683   W (ret);
11684   return ret;
11685 }
11686
11687 static int
11688 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11689 {
11690   unformat_input_t *i = vam->input;
11691   vl_api_l2tpv3_set_lookup_key_t *mp;
11692   u8 key = ~0;
11693   int ret;
11694
11695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (i, "lookup_v6_src"))
11698         key = L2T_LOOKUP_SRC_ADDRESS;
11699       else if (unformat (i, "lookup_v6_dst"))
11700         key = L2T_LOOKUP_DST_ADDRESS;
11701       else if (unformat (i, "lookup_session_id"))
11702         key = L2T_LOOKUP_SESSION_ID;
11703       else
11704         break;
11705     }
11706
11707   if (key == (u8) ~ 0)
11708     {
11709       errmsg ("l2tp session lookup key unset");
11710       return -99;
11711     }
11712
11713   M (L2TPV3_SET_LOOKUP_KEY, mp);
11714
11715   mp->key = key;
11716
11717   S (mp);
11718   W (ret);
11719   return ret;
11720 }
11721
11722 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11723   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11724 {
11725   vat_main_t *vam = &vat_main;
11726
11727   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11728          format_ip6_address, mp->our_address,
11729          format_ip6_address, mp->client_address,
11730          clib_net_to_host_u32 (mp->sw_if_index));
11731
11732   print (vam->ofp,
11733          "   local cookies %016llx %016llx remote cookie %016llx",
11734          clib_net_to_host_u64 (mp->local_cookie[0]),
11735          clib_net_to_host_u64 (mp->local_cookie[1]),
11736          clib_net_to_host_u64 (mp->remote_cookie));
11737
11738   print (vam->ofp, "   local session-id %d remote session-id %d",
11739          clib_net_to_host_u32 (mp->local_session_id),
11740          clib_net_to_host_u32 (mp->remote_session_id));
11741
11742   print (vam->ofp, "   l2 specific sublayer %s\n",
11743          mp->l2_sublayer_present ? "preset" : "absent");
11744
11745 }
11746
11747 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11748   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11749 {
11750   vat_main_t *vam = &vat_main;
11751   vat_json_node_t *node = NULL;
11752   struct in6_addr addr;
11753
11754   if (VAT_JSON_ARRAY != vam->json_tree.type)
11755     {
11756       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11757       vat_json_init_array (&vam->json_tree);
11758     }
11759   node = vat_json_array_add (&vam->json_tree);
11760
11761   vat_json_init_object (node);
11762
11763   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11764   vat_json_object_add_ip6 (node, "our_address", addr);
11765   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11766   vat_json_object_add_ip6 (node, "client_address", addr);
11767
11768   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11769   vat_json_init_array (lc);
11770   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11771   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11772   vat_json_object_add_uint (node, "remote_cookie",
11773                             clib_net_to_host_u64 (mp->remote_cookie));
11774
11775   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11776   vat_json_object_add_uint (node, "local_session_id",
11777                             clib_net_to_host_u32 (mp->local_session_id));
11778   vat_json_object_add_uint (node, "remote_session_id",
11779                             clib_net_to_host_u32 (mp->remote_session_id));
11780   vat_json_object_add_string_copy (node, "l2_sublayer",
11781                                    mp->l2_sublayer_present ? (u8 *) "present"
11782                                    : (u8 *) "absent");
11783 }
11784
11785 static int
11786 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11787 {
11788   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11789   vl_api_control_ping_t *mp_ping;
11790   int ret;
11791
11792   /* Get list of l2tpv3-tunnel interfaces */
11793   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11794   S (mp);
11795
11796   /* Use a control ping for synchronization */
11797   MPING (CONTROL_PING, mp_ping);
11798   S (mp_ping);
11799
11800   W (ret);
11801   return ret;
11802 }
11803
11804
11805 static void vl_api_sw_interface_tap_details_t_handler
11806   (vl_api_sw_interface_tap_details_t * mp)
11807 {
11808   vat_main_t *vam = &vat_main;
11809
11810   print (vam->ofp, "%-16s %d",
11811          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11812 }
11813
11814 static void vl_api_sw_interface_tap_details_t_handler_json
11815   (vl_api_sw_interface_tap_details_t * mp)
11816 {
11817   vat_main_t *vam = &vat_main;
11818   vat_json_node_t *node = NULL;
11819
11820   if (VAT_JSON_ARRAY != vam->json_tree.type)
11821     {
11822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11823       vat_json_init_array (&vam->json_tree);
11824     }
11825   node = vat_json_array_add (&vam->json_tree);
11826
11827   vat_json_init_object (node);
11828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11829   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11830 }
11831
11832 static int
11833 api_sw_interface_tap_dump (vat_main_t * vam)
11834 {
11835   vl_api_sw_interface_tap_dump_t *mp;
11836   vl_api_control_ping_t *mp_ping;
11837   int ret;
11838
11839   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11840   /* Get list of tap interfaces */
11841   M (SW_INTERFACE_TAP_DUMP, mp);
11842   S (mp);
11843
11844   /* Use a control ping for synchronization */
11845   MPING (CONTROL_PING, mp_ping);
11846   S (mp_ping);
11847
11848   W (ret);
11849   return ret;
11850 }
11851
11852 static uword unformat_vxlan_decap_next
11853   (unformat_input_t * input, va_list * args)
11854 {
11855   u32 *result = va_arg (*args, u32 *);
11856   u32 tmp;
11857
11858   if (unformat (input, "l2"))
11859     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11860   else if (unformat (input, "%d", &tmp))
11861     *result = tmp;
11862   else
11863     return 0;
11864   return 1;
11865 }
11866
11867 static int
11868 api_vxlan_add_del_tunnel (vat_main_t * vam)
11869 {
11870   unformat_input_t *line_input = vam->input;
11871   vl_api_vxlan_add_del_tunnel_t *mp;
11872   ip46_address_t src, dst;
11873   u8 is_add = 1;
11874   u8 ipv4_set = 0, ipv6_set = 0;
11875   u8 src_set = 0;
11876   u8 dst_set = 0;
11877   u8 grp_set = 0;
11878   u32 mcast_sw_if_index = ~0;
11879   u32 encap_vrf_id = 0;
11880   u32 decap_next_index = ~0;
11881   u32 vni = 0;
11882   int ret;
11883
11884   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11885   memset (&src, 0, sizeof src);
11886   memset (&dst, 0, sizeof dst);
11887
11888   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11889     {
11890       if (unformat (line_input, "del"))
11891         is_add = 0;
11892       else
11893         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11894         {
11895           ipv4_set = 1;
11896           src_set = 1;
11897         }
11898       else
11899         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11900         {
11901           ipv4_set = 1;
11902           dst_set = 1;
11903         }
11904       else
11905         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11906         {
11907           ipv6_set = 1;
11908           src_set = 1;
11909         }
11910       else
11911         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11912         {
11913           ipv6_set = 1;
11914           dst_set = 1;
11915         }
11916       else if (unformat (line_input, "group %U %U",
11917                          unformat_ip4_address, &dst.ip4,
11918                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11919         {
11920           grp_set = dst_set = 1;
11921           ipv4_set = 1;
11922         }
11923       else if (unformat (line_input, "group %U",
11924                          unformat_ip4_address, &dst.ip4))
11925         {
11926           grp_set = dst_set = 1;
11927           ipv4_set = 1;
11928         }
11929       else if (unformat (line_input, "group %U %U",
11930                          unformat_ip6_address, &dst.ip6,
11931                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11932         {
11933           grp_set = dst_set = 1;
11934           ipv6_set = 1;
11935         }
11936       else if (unformat (line_input, "group %U",
11937                          unformat_ip6_address, &dst.ip6))
11938         {
11939           grp_set = dst_set = 1;
11940           ipv6_set = 1;
11941         }
11942       else
11943         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11944         ;
11945       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11946         ;
11947       else if (unformat (line_input, "decap-next %U",
11948                          unformat_vxlan_decap_next, &decap_next_index))
11949         ;
11950       else if (unformat (line_input, "vni %d", &vni))
11951         ;
11952       else
11953         {
11954           errmsg ("parse error '%U'", format_unformat_error, line_input);
11955           return -99;
11956         }
11957     }
11958
11959   if (src_set == 0)
11960     {
11961       errmsg ("tunnel src address not specified");
11962       return -99;
11963     }
11964   if (dst_set == 0)
11965     {
11966       errmsg ("tunnel dst address not specified");
11967       return -99;
11968     }
11969
11970   if (grp_set && !ip46_address_is_multicast (&dst))
11971     {
11972       errmsg ("tunnel group address not multicast");
11973       return -99;
11974     }
11975   if (grp_set && mcast_sw_if_index == ~0)
11976     {
11977       errmsg ("tunnel nonexistent multicast device");
11978       return -99;
11979     }
11980   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11981     {
11982       errmsg ("tunnel dst address must be unicast");
11983       return -99;
11984     }
11985
11986
11987   if (ipv4_set && ipv6_set)
11988     {
11989       errmsg ("both IPv4 and IPv6 addresses specified");
11990       return -99;
11991     }
11992
11993   if ((vni == 0) || (vni >> 24))
11994     {
11995       errmsg ("vni not specified or out of range");
11996       return -99;
11997     }
11998
11999   M (VXLAN_ADD_DEL_TUNNEL, mp);
12000
12001   if (ipv6_set)
12002     {
12003       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12004       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12005     }
12006   else
12007     {
12008       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12009       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12010     }
12011   mp->encap_vrf_id = ntohl (encap_vrf_id);
12012   mp->decap_next_index = ntohl (decap_next_index);
12013   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12014   mp->vni = ntohl (vni);
12015   mp->is_add = is_add;
12016   mp->is_ipv6 = ipv6_set;
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static void vl_api_vxlan_tunnel_details_t_handler
12024   (vl_api_vxlan_tunnel_details_t * mp)
12025 {
12026   vat_main_t *vam = &vat_main;
12027   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12028   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12029
12030   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12031          ntohl (mp->sw_if_index),
12032          format_ip46_address, &src, IP46_TYPE_ANY,
12033          format_ip46_address, &dst, IP46_TYPE_ANY,
12034          ntohl (mp->encap_vrf_id),
12035          ntohl (mp->decap_next_index), ntohl (mp->vni),
12036          ntohl (mp->mcast_sw_if_index));
12037 }
12038
12039 static void vl_api_vxlan_tunnel_details_t_handler_json
12040   (vl_api_vxlan_tunnel_details_t * mp)
12041 {
12042   vat_main_t *vam = &vat_main;
12043   vat_json_node_t *node = NULL;
12044
12045   if (VAT_JSON_ARRAY != vam->json_tree.type)
12046     {
12047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12048       vat_json_init_array (&vam->json_tree);
12049     }
12050   node = vat_json_array_add (&vam->json_tree);
12051
12052   vat_json_init_object (node);
12053   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12054   if (mp->is_ipv6)
12055     {
12056       struct in6_addr ip6;
12057
12058       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12059       vat_json_object_add_ip6 (node, "src_address", ip6);
12060       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12061       vat_json_object_add_ip6 (node, "dst_address", ip6);
12062     }
12063   else
12064     {
12065       struct in_addr ip4;
12066
12067       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12068       vat_json_object_add_ip4 (node, "src_address", ip4);
12069       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12070       vat_json_object_add_ip4 (node, "dst_address", ip4);
12071     }
12072   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12073   vat_json_object_add_uint (node, "decap_next_index",
12074                             ntohl (mp->decap_next_index));
12075   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12076   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12077   vat_json_object_add_uint (node, "mcast_sw_if_index",
12078                             ntohl (mp->mcast_sw_if_index));
12079 }
12080
12081 static int
12082 api_vxlan_tunnel_dump (vat_main_t * vam)
12083 {
12084   unformat_input_t *i = vam->input;
12085   vl_api_vxlan_tunnel_dump_t *mp;
12086   vl_api_control_ping_t *mp_ping;
12087   u32 sw_if_index;
12088   u8 sw_if_index_set = 0;
12089   int ret;
12090
12091   /* Parse args required to build the message */
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "sw_if_index %d", &sw_if_index))
12095         sw_if_index_set = 1;
12096       else
12097         break;
12098     }
12099
12100   if (sw_if_index_set == 0)
12101     {
12102       sw_if_index = ~0;
12103     }
12104
12105   if (!vam->json_output)
12106     {
12107       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12108              "sw_if_index", "src_address", "dst_address",
12109              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12110     }
12111
12112   /* Get list of vxlan-tunnel interfaces */
12113   M (VXLAN_TUNNEL_DUMP, mp);
12114
12115   mp->sw_if_index = htonl (sw_if_index);
12116
12117   S (mp);
12118
12119   /* Use a control ping for synchronization */
12120   MPING (CONTROL_PING, mp_ping);
12121   S (mp_ping);
12122
12123   W (ret);
12124   return ret;
12125 }
12126
12127 static uword unformat_geneve_decap_next
12128   (unformat_input_t * input, va_list * args)
12129 {
12130   u32 *result = va_arg (*args, u32 *);
12131   u32 tmp;
12132
12133   if (unformat (input, "l2"))
12134     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12135   else if (unformat (input, "%d", &tmp))
12136     *result = tmp;
12137   else
12138     return 0;
12139   return 1;
12140 }
12141
12142 static int
12143 api_geneve_add_del_tunnel (vat_main_t * vam)
12144 {
12145   unformat_input_t *line_input = vam->input;
12146   vl_api_geneve_add_del_tunnel_t *mp;
12147   ip46_address_t src, dst;
12148   u8 is_add = 1;
12149   u8 ipv4_set = 0, ipv6_set = 0;
12150   u8 src_set = 0;
12151   u8 dst_set = 0;
12152   u8 grp_set = 0;
12153   u32 mcast_sw_if_index = ~0;
12154   u32 encap_vrf_id = 0;
12155   u32 decap_next_index = ~0;
12156   u32 vni = 0;
12157   int ret;
12158
12159   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12160   memset (&src, 0, sizeof src);
12161   memset (&dst, 0, sizeof dst);
12162
12163   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12164     {
12165       if (unformat (line_input, "del"))
12166         is_add = 0;
12167       else
12168         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12169         {
12170           ipv4_set = 1;
12171           src_set = 1;
12172         }
12173       else
12174         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12175         {
12176           ipv4_set = 1;
12177           dst_set = 1;
12178         }
12179       else
12180         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12181         {
12182           ipv6_set = 1;
12183           src_set = 1;
12184         }
12185       else
12186         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12187         {
12188           ipv6_set = 1;
12189           dst_set = 1;
12190         }
12191       else if (unformat (line_input, "group %U %U",
12192                          unformat_ip4_address, &dst.ip4,
12193                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12194         {
12195           grp_set = dst_set = 1;
12196           ipv4_set = 1;
12197         }
12198       else if (unformat (line_input, "group %U",
12199                          unformat_ip4_address, &dst.ip4))
12200         {
12201           grp_set = dst_set = 1;
12202           ipv4_set = 1;
12203         }
12204       else if (unformat (line_input, "group %U %U",
12205                          unformat_ip6_address, &dst.ip6,
12206                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12207         {
12208           grp_set = dst_set = 1;
12209           ipv6_set = 1;
12210         }
12211       else if (unformat (line_input, "group %U",
12212                          unformat_ip6_address, &dst.ip6))
12213         {
12214           grp_set = dst_set = 1;
12215           ipv6_set = 1;
12216         }
12217       else
12218         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12219         ;
12220       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12221         ;
12222       else if (unformat (line_input, "decap-next %U",
12223                          unformat_geneve_decap_next, &decap_next_index))
12224         ;
12225       else if (unformat (line_input, "vni %d", &vni))
12226         ;
12227       else
12228         {
12229           errmsg ("parse error '%U'", format_unformat_error, line_input);
12230           return -99;
12231         }
12232     }
12233
12234   if (src_set == 0)
12235     {
12236       errmsg ("tunnel src address not specified");
12237       return -99;
12238     }
12239   if (dst_set == 0)
12240     {
12241       errmsg ("tunnel dst address not specified");
12242       return -99;
12243     }
12244
12245   if (grp_set && !ip46_address_is_multicast (&dst))
12246     {
12247       errmsg ("tunnel group address not multicast");
12248       return -99;
12249     }
12250   if (grp_set && mcast_sw_if_index == ~0)
12251     {
12252       errmsg ("tunnel nonexistent multicast device");
12253       return -99;
12254     }
12255   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12256     {
12257       errmsg ("tunnel dst address must be unicast");
12258       return -99;
12259     }
12260
12261
12262   if (ipv4_set && ipv6_set)
12263     {
12264       errmsg ("both IPv4 and IPv6 addresses specified");
12265       return -99;
12266     }
12267
12268   if ((vni == 0) || (vni >> 24))
12269     {
12270       errmsg ("vni not specified or out of range");
12271       return -99;
12272     }
12273
12274   M (GENEVE_ADD_DEL_TUNNEL, mp);
12275
12276   if (ipv6_set)
12277     {
12278       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12279       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12280     }
12281   else
12282     {
12283       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12284       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12285     }
12286   mp->encap_vrf_id = ntohl (encap_vrf_id);
12287   mp->decap_next_index = ntohl (decap_next_index);
12288   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12289   mp->vni = ntohl (vni);
12290   mp->is_add = is_add;
12291   mp->is_ipv6 = ipv6_set;
12292
12293   S (mp);
12294   W (ret);
12295   return ret;
12296 }
12297
12298 static void vl_api_geneve_tunnel_details_t_handler
12299   (vl_api_geneve_tunnel_details_t * mp)
12300 {
12301   vat_main_t *vam = &vat_main;
12302   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12303   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12304
12305   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12306          ntohl (mp->sw_if_index),
12307          format_ip46_address, &src, IP46_TYPE_ANY,
12308          format_ip46_address, &dst, IP46_TYPE_ANY,
12309          ntohl (mp->encap_vrf_id),
12310          ntohl (mp->decap_next_index), ntohl (mp->vni),
12311          ntohl (mp->mcast_sw_if_index));
12312 }
12313
12314 static void vl_api_geneve_tunnel_details_t_handler_json
12315   (vl_api_geneve_tunnel_details_t * mp)
12316 {
12317   vat_main_t *vam = &vat_main;
12318   vat_json_node_t *node = NULL;
12319
12320   if (VAT_JSON_ARRAY != vam->json_tree.type)
12321     {
12322       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12323       vat_json_init_array (&vam->json_tree);
12324     }
12325   node = vat_json_array_add (&vam->json_tree);
12326
12327   vat_json_init_object (node);
12328   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12329   if (mp->is_ipv6)
12330     {
12331       struct in6_addr ip6;
12332
12333       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12334       vat_json_object_add_ip6 (node, "src_address", ip6);
12335       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12336       vat_json_object_add_ip6 (node, "dst_address", ip6);
12337     }
12338   else
12339     {
12340       struct in_addr ip4;
12341
12342       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12343       vat_json_object_add_ip4 (node, "src_address", ip4);
12344       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12345       vat_json_object_add_ip4 (node, "dst_address", ip4);
12346     }
12347   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12348   vat_json_object_add_uint (node, "decap_next_index",
12349                             ntohl (mp->decap_next_index));
12350   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12351   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12352   vat_json_object_add_uint (node, "mcast_sw_if_index",
12353                             ntohl (mp->mcast_sw_if_index));
12354 }
12355
12356 static int
12357 api_geneve_tunnel_dump (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   vl_api_geneve_tunnel_dump_t *mp;
12361   vl_api_control_ping_t *mp_ping;
12362   u32 sw_if_index;
12363   u8 sw_if_index_set = 0;
12364   int ret;
12365
12366   /* Parse args required to build the message */
12367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12368     {
12369       if (unformat (i, "sw_if_index %d", &sw_if_index))
12370         sw_if_index_set = 1;
12371       else
12372         break;
12373     }
12374
12375   if (sw_if_index_set == 0)
12376     {
12377       sw_if_index = ~0;
12378     }
12379
12380   if (!vam->json_output)
12381     {
12382       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12383              "sw_if_index", "local_address", "remote_address",
12384              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12385     }
12386
12387   /* Get list of geneve-tunnel interfaces */
12388   M (GENEVE_TUNNEL_DUMP, mp);
12389
12390   mp->sw_if_index = htonl (sw_if_index);
12391
12392   S (mp);
12393
12394   /* Use a control ping for synchronization */
12395   M (CONTROL_PING, mp_ping);
12396   S (mp_ping);
12397
12398   W (ret);
12399   return ret;
12400 }
12401
12402 static int
12403 api_gre_add_del_tunnel (vat_main_t * vam)
12404 {
12405   unformat_input_t *line_input = vam->input;
12406   vl_api_gre_add_del_tunnel_t *mp;
12407   ip4_address_t src4, dst4;
12408   ip6_address_t src6, dst6;
12409   u8 is_add = 1;
12410   u8 ipv4_set = 0;
12411   u8 ipv6_set = 0;
12412   u8 teb = 0;
12413   u8 src_set = 0;
12414   u8 dst_set = 0;
12415   u32 outer_fib_id = 0;
12416   int ret;
12417
12418   memset (&src4, 0, sizeof src4);
12419   memset (&dst4, 0, sizeof dst4);
12420   memset (&src6, 0, sizeof src6);
12421   memset (&dst6, 0, sizeof dst6);
12422
12423   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12424     {
12425       if (unformat (line_input, "del"))
12426         is_add = 0;
12427       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12428         {
12429           src_set = 1;
12430           ipv4_set = 1;
12431         }
12432       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12433         {
12434           dst_set = 1;
12435           ipv4_set = 1;
12436         }
12437       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12438         {
12439           src_set = 1;
12440           ipv6_set = 1;
12441         }
12442       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12443         {
12444           dst_set = 1;
12445           ipv6_set = 1;
12446         }
12447       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12448         ;
12449       else if (unformat (line_input, "teb"))
12450         teb = 1;
12451       else
12452         {
12453           errmsg ("parse error '%U'", format_unformat_error, line_input);
12454           return -99;
12455         }
12456     }
12457
12458   if (src_set == 0)
12459     {
12460       errmsg ("tunnel src address not specified");
12461       return -99;
12462     }
12463   if (dst_set == 0)
12464     {
12465       errmsg ("tunnel dst address not specified");
12466       return -99;
12467     }
12468   if (ipv4_set && ipv6_set)
12469     {
12470       errmsg ("both IPv4 and IPv6 addresses specified");
12471       return -99;
12472     }
12473
12474
12475   M (GRE_ADD_DEL_TUNNEL, mp);
12476
12477   if (ipv4_set)
12478     {
12479       clib_memcpy (&mp->src_address, &src4, 4);
12480       clib_memcpy (&mp->dst_address, &dst4, 4);
12481     }
12482   else
12483     {
12484       clib_memcpy (&mp->src_address, &src6, 16);
12485       clib_memcpy (&mp->dst_address, &dst6, 16);
12486     }
12487   mp->outer_fib_id = ntohl (outer_fib_id);
12488   mp->is_add = is_add;
12489   mp->teb = teb;
12490   mp->is_ipv6 = ipv6_set;
12491
12492   S (mp);
12493   W (ret);
12494   return ret;
12495 }
12496
12497 static void vl_api_gre_tunnel_details_t_handler
12498   (vl_api_gre_tunnel_details_t * mp)
12499 {
12500   vat_main_t *vam = &vat_main;
12501   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12502   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12503
12504   print (vam->ofp, "%11d%24U%24U%6d%14d",
12505          ntohl (mp->sw_if_index),
12506          format_ip46_address, &src, IP46_TYPE_ANY,
12507          format_ip46_address, &dst, IP46_TYPE_ANY,
12508          mp->teb, ntohl (mp->outer_fib_id));
12509 }
12510
12511 static void vl_api_gre_tunnel_details_t_handler_json
12512   (vl_api_gre_tunnel_details_t * mp)
12513 {
12514   vat_main_t *vam = &vat_main;
12515   vat_json_node_t *node = NULL;
12516   struct in_addr ip4;
12517   struct in6_addr ip6;
12518
12519   if (VAT_JSON_ARRAY != vam->json_tree.type)
12520     {
12521       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12522       vat_json_init_array (&vam->json_tree);
12523     }
12524   node = vat_json_array_add (&vam->json_tree);
12525
12526   vat_json_init_object (node);
12527   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12528   if (!mp->is_ipv6)
12529     {
12530       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12531       vat_json_object_add_ip4 (node, "src_address", ip4);
12532       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12533       vat_json_object_add_ip4 (node, "dst_address", ip4);
12534     }
12535   else
12536     {
12537       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12538       vat_json_object_add_ip6 (node, "src_address", ip6);
12539       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12540       vat_json_object_add_ip6 (node, "dst_address", ip6);
12541     }
12542   vat_json_object_add_uint (node, "teb", mp->teb);
12543   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12544   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12545 }
12546
12547 static int
12548 api_gre_tunnel_dump (vat_main_t * vam)
12549 {
12550   unformat_input_t *i = vam->input;
12551   vl_api_gre_tunnel_dump_t *mp;
12552   vl_api_control_ping_t *mp_ping;
12553   u32 sw_if_index;
12554   u8 sw_if_index_set = 0;
12555   int ret;
12556
12557   /* Parse args required to build the message */
12558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12559     {
12560       if (unformat (i, "sw_if_index %d", &sw_if_index))
12561         sw_if_index_set = 1;
12562       else
12563         break;
12564     }
12565
12566   if (sw_if_index_set == 0)
12567     {
12568       sw_if_index = ~0;
12569     }
12570
12571   if (!vam->json_output)
12572     {
12573       print (vam->ofp, "%11s%24s%24s%6s%14s",
12574              "sw_if_index", "src_address", "dst_address", "teb",
12575              "outer_fib_id");
12576     }
12577
12578   /* Get list of gre-tunnel interfaces */
12579   M (GRE_TUNNEL_DUMP, mp);
12580
12581   mp->sw_if_index = htonl (sw_if_index);
12582
12583   S (mp);
12584
12585   /* Use a control ping for synchronization */
12586   MPING (CONTROL_PING, mp_ping);
12587   S (mp_ping);
12588
12589   W (ret);
12590   return ret;
12591 }
12592
12593 static int
12594 api_l2_fib_clear_table (vat_main_t * vam)
12595 {
12596 //  unformat_input_t * i = vam->input;
12597   vl_api_l2_fib_clear_table_t *mp;
12598   int ret;
12599
12600   M (L2_FIB_CLEAR_TABLE, mp);
12601
12602   S (mp);
12603   W (ret);
12604   return ret;
12605 }
12606
12607 static int
12608 api_l2_interface_efp_filter (vat_main_t * vam)
12609 {
12610   unformat_input_t *i = vam->input;
12611   vl_api_l2_interface_efp_filter_t *mp;
12612   u32 sw_if_index;
12613   u8 enable = 1;
12614   u8 sw_if_index_set = 0;
12615   int ret;
12616
12617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12618     {
12619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12620         sw_if_index_set = 1;
12621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12622         sw_if_index_set = 1;
12623       else if (unformat (i, "enable"))
12624         enable = 1;
12625       else if (unformat (i, "disable"))
12626         enable = 0;
12627       else
12628         {
12629           clib_warning ("parse error '%U'", format_unformat_error, i);
12630           return -99;
12631         }
12632     }
12633
12634   if (sw_if_index_set == 0)
12635     {
12636       errmsg ("missing sw_if_index");
12637       return -99;
12638     }
12639
12640   M (L2_INTERFACE_EFP_FILTER, mp);
12641
12642   mp->sw_if_index = ntohl (sw_if_index);
12643   mp->enable_disable = enable;
12644
12645   S (mp);
12646   W (ret);
12647   return ret;
12648 }
12649
12650 #define foreach_vtr_op                          \
12651 _("disable",  L2_VTR_DISABLED)                  \
12652 _("push-1",  L2_VTR_PUSH_1)                     \
12653 _("push-2",  L2_VTR_PUSH_2)                     \
12654 _("pop-1",  L2_VTR_POP_1)                       \
12655 _("pop-2",  L2_VTR_POP_2)                       \
12656 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12657 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12658 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12659 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12660
12661 static int
12662 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12666   u32 sw_if_index;
12667   u8 sw_if_index_set = 0;
12668   u8 vtr_op_set = 0;
12669   u32 vtr_op = 0;
12670   u32 push_dot1q = 1;
12671   u32 tag1 = ~0;
12672   u32 tag2 = ~0;
12673   int ret;
12674
12675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12676     {
12677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12678         sw_if_index_set = 1;
12679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12680         sw_if_index_set = 1;
12681       else if (unformat (i, "vtr_op %d", &vtr_op))
12682         vtr_op_set = 1;
12683 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12684       foreach_vtr_op
12685 #undef _
12686         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12687         ;
12688       else if (unformat (i, "tag1 %d", &tag1))
12689         ;
12690       else if (unformat (i, "tag2 %d", &tag2))
12691         ;
12692       else
12693         {
12694           clib_warning ("parse error '%U'", format_unformat_error, i);
12695           return -99;
12696         }
12697     }
12698
12699   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12700     {
12701       errmsg ("missing vtr operation or sw_if_index");
12702       return -99;
12703     }
12704
12705   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12706   mp->sw_if_index = ntohl (sw_if_index);
12707   mp->vtr_op = ntohl (vtr_op);
12708   mp->push_dot1q = ntohl (push_dot1q);
12709   mp->tag1 = ntohl (tag1);
12710   mp->tag2 = ntohl (tag2);
12711
12712   S (mp);
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static int
12718 api_create_vhost_user_if (vat_main_t * vam)
12719 {
12720   unformat_input_t *i = vam->input;
12721   vl_api_create_vhost_user_if_t *mp;
12722   u8 *file_name;
12723   u8 is_server = 0;
12724   u8 file_name_set = 0;
12725   u32 custom_dev_instance = ~0;
12726   u8 hwaddr[6];
12727   u8 use_custom_mac = 0;
12728   u8 *tag = 0;
12729   int ret;
12730
12731   /* Shut up coverity */
12732   memset (hwaddr, 0, sizeof (hwaddr));
12733
12734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (i, "socket %s", &file_name))
12737         {
12738           file_name_set = 1;
12739         }
12740       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12741         ;
12742       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12743         use_custom_mac = 1;
12744       else if (unformat (i, "server"))
12745         is_server = 1;
12746       else if (unformat (i, "tag %s", &tag))
12747         ;
12748       else
12749         break;
12750     }
12751
12752   if (file_name_set == 0)
12753     {
12754       errmsg ("missing socket file name");
12755       return -99;
12756     }
12757
12758   if (vec_len (file_name) > 255)
12759     {
12760       errmsg ("socket file name too long");
12761       return -99;
12762     }
12763   vec_add1 (file_name, 0);
12764
12765   M (CREATE_VHOST_USER_IF, mp);
12766
12767   mp->is_server = is_server;
12768   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12769   vec_free (file_name);
12770   if (custom_dev_instance != ~0)
12771     {
12772       mp->renumber = 1;
12773       mp->custom_dev_instance = ntohl (custom_dev_instance);
12774     }
12775   mp->use_custom_mac = use_custom_mac;
12776   clib_memcpy (mp->mac_address, hwaddr, 6);
12777   if (tag)
12778     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12779   vec_free (tag);
12780
12781   S (mp);
12782   W (ret);
12783   return ret;
12784 }
12785
12786 static int
12787 api_modify_vhost_user_if (vat_main_t * vam)
12788 {
12789   unformat_input_t *i = vam->input;
12790   vl_api_modify_vhost_user_if_t *mp;
12791   u8 *file_name;
12792   u8 is_server = 0;
12793   u8 file_name_set = 0;
12794   u32 custom_dev_instance = ~0;
12795   u8 sw_if_index_set = 0;
12796   u32 sw_if_index = (u32) ~ 0;
12797   int ret;
12798
12799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12800     {
12801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12802         sw_if_index_set = 1;
12803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12804         sw_if_index_set = 1;
12805       else if (unformat (i, "socket %s", &file_name))
12806         {
12807           file_name_set = 1;
12808         }
12809       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12810         ;
12811       else if (unformat (i, "server"))
12812         is_server = 1;
12813       else
12814         break;
12815     }
12816
12817   if (sw_if_index_set == 0)
12818     {
12819       errmsg ("missing sw_if_index or interface name");
12820       return -99;
12821     }
12822
12823   if (file_name_set == 0)
12824     {
12825       errmsg ("missing socket file name");
12826       return -99;
12827     }
12828
12829   if (vec_len (file_name) > 255)
12830     {
12831       errmsg ("socket file name too long");
12832       return -99;
12833     }
12834   vec_add1 (file_name, 0);
12835
12836   M (MODIFY_VHOST_USER_IF, mp);
12837
12838   mp->sw_if_index = ntohl (sw_if_index);
12839   mp->is_server = is_server;
12840   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12841   vec_free (file_name);
12842   if (custom_dev_instance != ~0)
12843     {
12844       mp->renumber = 1;
12845       mp->custom_dev_instance = ntohl (custom_dev_instance);
12846     }
12847
12848   S (mp);
12849   W (ret);
12850   return ret;
12851 }
12852
12853 static int
12854 api_delete_vhost_user_if (vat_main_t * vam)
12855 {
12856   unformat_input_t *i = vam->input;
12857   vl_api_delete_vhost_user_if_t *mp;
12858   u32 sw_if_index = ~0;
12859   u8 sw_if_index_set = 0;
12860   int ret;
12861
12862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12863     {
12864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12865         sw_if_index_set = 1;
12866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12867         sw_if_index_set = 1;
12868       else
12869         break;
12870     }
12871
12872   if (sw_if_index_set == 0)
12873     {
12874       errmsg ("missing sw_if_index or interface name");
12875       return -99;
12876     }
12877
12878
12879   M (DELETE_VHOST_USER_IF, mp);
12880
12881   mp->sw_if_index = ntohl (sw_if_index);
12882
12883   S (mp);
12884   W (ret);
12885   return ret;
12886 }
12887
12888 static void vl_api_sw_interface_vhost_user_details_t_handler
12889   (vl_api_sw_interface_vhost_user_details_t * mp)
12890 {
12891   vat_main_t *vam = &vat_main;
12892
12893   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12894          (char *) mp->interface_name,
12895          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12896          clib_net_to_host_u64 (mp->features), mp->is_server,
12897          ntohl (mp->num_regions), (char *) mp->sock_filename);
12898   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12899 }
12900
12901 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12902   (vl_api_sw_interface_vhost_user_details_t * mp)
12903 {
12904   vat_main_t *vam = &vat_main;
12905   vat_json_node_t *node = NULL;
12906
12907   if (VAT_JSON_ARRAY != vam->json_tree.type)
12908     {
12909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12910       vat_json_init_array (&vam->json_tree);
12911     }
12912   node = vat_json_array_add (&vam->json_tree);
12913
12914   vat_json_init_object (node);
12915   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12916   vat_json_object_add_string_copy (node, "interface_name",
12917                                    mp->interface_name);
12918   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12919                             ntohl (mp->virtio_net_hdr_sz));
12920   vat_json_object_add_uint (node, "features",
12921                             clib_net_to_host_u64 (mp->features));
12922   vat_json_object_add_uint (node, "is_server", mp->is_server);
12923   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12924   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12925   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12926 }
12927
12928 static int
12929 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12930 {
12931   vl_api_sw_interface_vhost_user_dump_t *mp;
12932   vl_api_control_ping_t *mp_ping;
12933   int ret;
12934   print (vam->ofp,
12935          "Interface name            idx hdr_sz features server regions filename");
12936
12937   /* Get list of vhost-user interfaces */
12938   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12939   S (mp);
12940
12941   /* Use a control ping for synchronization */
12942   MPING (CONTROL_PING, mp_ping);
12943   S (mp_ping);
12944
12945   W (ret);
12946   return ret;
12947 }
12948
12949 static int
12950 api_show_version (vat_main_t * vam)
12951 {
12952   vl_api_show_version_t *mp;
12953   int ret;
12954
12955   M (SHOW_VERSION, mp);
12956
12957   S (mp);
12958   W (ret);
12959   return ret;
12960 }
12961
12962
12963 static int
12964 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12965 {
12966   unformat_input_t *line_input = vam->input;
12967   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12968   ip4_address_t local4, remote4;
12969   ip6_address_t local6, remote6;
12970   u8 is_add = 1;
12971   u8 ipv4_set = 0, ipv6_set = 0;
12972   u8 local_set = 0;
12973   u8 remote_set = 0;
12974   u8 grp_set = 0;
12975   u32 mcast_sw_if_index = ~0;
12976   u32 encap_vrf_id = 0;
12977   u32 decap_vrf_id = 0;
12978   u8 protocol = ~0;
12979   u32 vni;
12980   u8 vni_set = 0;
12981   int ret;
12982
12983   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12984   memset (&local4, 0, sizeof local4);
12985   memset (&remote4, 0, sizeof remote4);
12986   memset (&local6, 0, sizeof local6);
12987   memset (&remote6, 0, sizeof remote6);
12988
12989   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat (line_input, "del"))
12992         is_add = 0;
12993       else if (unformat (line_input, "local %U",
12994                          unformat_ip4_address, &local4))
12995         {
12996           local_set = 1;
12997           ipv4_set = 1;
12998         }
12999       else if (unformat (line_input, "remote %U",
13000                          unformat_ip4_address, &remote4))
13001         {
13002           remote_set = 1;
13003           ipv4_set = 1;
13004         }
13005       else if (unformat (line_input, "local %U",
13006                          unformat_ip6_address, &local6))
13007         {
13008           local_set = 1;
13009           ipv6_set = 1;
13010         }
13011       else if (unformat (line_input, "remote %U",
13012                          unformat_ip6_address, &remote6))
13013         {
13014           remote_set = 1;
13015           ipv6_set = 1;
13016         }
13017       else if (unformat (line_input, "group %U %U",
13018                          unformat_ip4_address, &remote4,
13019                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13020         {
13021           grp_set = remote_set = 1;
13022           ipv4_set = 1;
13023         }
13024       else if (unformat (line_input, "group %U",
13025                          unformat_ip4_address, &remote4))
13026         {
13027           grp_set = remote_set = 1;
13028           ipv4_set = 1;
13029         }
13030       else if (unformat (line_input, "group %U %U",
13031                          unformat_ip6_address, &remote6,
13032                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13033         {
13034           grp_set = remote_set = 1;
13035           ipv6_set = 1;
13036         }
13037       else if (unformat (line_input, "group %U",
13038                          unformat_ip6_address, &remote6))
13039         {
13040           grp_set = remote_set = 1;
13041           ipv6_set = 1;
13042         }
13043       else
13044         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13045         ;
13046       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13047         ;
13048       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13049         ;
13050       else if (unformat (line_input, "vni %d", &vni))
13051         vni_set = 1;
13052       else if (unformat (line_input, "next-ip4"))
13053         protocol = 1;
13054       else if (unformat (line_input, "next-ip6"))
13055         protocol = 2;
13056       else if (unformat (line_input, "next-ethernet"))
13057         protocol = 3;
13058       else if (unformat (line_input, "next-nsh"))
13059         protocol = 4;
13060       else
13061         {
13062           errmsg ("parse error '%U'", format_unformat_error, line_input);
13063           return -99;
13064         }
13065     }
13066
13067   if (local_set == 0)
13068     {
13069       errmsg ("tunnel local address not specified");
13070       return -99;
13071     }
13072   if (remote_set == 0)
13073     {
13074       errmsg ("tunnel remote address not specified");
13075       return -99;
13076     }
13077   if (grp_set && mcast_sw_if_index == ~0)
13078     {
13079       errmsg ("tunnel nonexistent multicast device");
13080       return -99;
13081     }
13082   if (ipv4_set && ipv6_set)
13083     {
13084       errmsg ("both IPv4 and IPv6 addresses specified");
13085       return -99;
13086     }
13087
13088   if (vni_set == 0)
13089     {
13090       errmsg ("vni not specified");
13091       return -99;
13092     }
13093
13094   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13095
13096
13097   if (ipv6_set)
13098     {
13099       clib_memcpy (&mp->local, &local6, sizeof (local6));
13100       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13101     }
13102   else
13103     {
13104       clib_memcpy (&mp->local, &local4, sizeof (local4));
13105       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13106     }
13107
13108   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13109   mp->encap_vrf_id = ntohl (encap_vrf_id);
13110   mp->decap_vrf_id = ntohl (decap_vrf_id);
13111   mp->protocol = protocol;
13112   mp->vni = ntohl (vni);
13113   mp->is_add = is_add;
13114   mp->is_ipv6 = ipv6_set;
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13122   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13123 {
13124   vat_main_t *vam = &vat_main;
13125   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13126   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13127
13128   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13129          ntohl (mp->sw_if_index),
13130          format_ip46_address, &local, IP46_TYPE_ANY,
13131          format_ip46_address, &remote, IP46_TYPE_ANY,
13132          ntohl (mp->vni), mp->protocol,
13133          ntohl (mp->mcast_sw_if_index),
13134          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13135 }
13136
13137
13138 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13139   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13140 {
13141   vat_main_t *vam = &vat_main;
13142   vat_json_node_t *node = NULL;
13143   struct in_addr ip4;
13144   struct in6_addr ip6;
13145
13146   if (VAT_JSON_ARRAY != vam->json_tree.type)
13147     {
13148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13149       vat_json_init_array (&vam->json_tree);
13150     }
13151   node = vat_json_array_add (&vam->json_tree);
13152
13153   vat_json_init_object (node);
13154   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13155   if (mp->is_ipv6)
13156     {
13157       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13158       vat_json_object_add_ip6 (node, "local", ip6);
13159       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13160       vat_json_object_add_ip6 (node, "remote", ip6);
13161     }
13162   else
13163     {
13164       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13165       vat_json_object_add_ip4 (node, "local", ip4);
13166       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13167       vat_json_object_add_ip4 (node, "remote", ip4);
13168     }
13169   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13170   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13171   vat_json_object_add_uint (node, "mcast_sw_if_index",
13172                             ntohl (mp->mcast_sw_if_index));
13173   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13174   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13175   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13176 }
13177
13178 static int
13179 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13180 {
13181   unformat_input_t *i = vam->input;
13182   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13183   vl_api_control_ping_t *mp_ping;
13184   u32 sw_if_index;
13185   u8 sw_if_index_set = 0;
13186   int ret;
13187
13188   /* Parse args required to build the message */
13189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13190     {
13191       if (unformat (i, "sw_if_index %d", &sw_if_index))
13192         sw_if_index_set = 1;
13193       else
13194         break;
13195     }
13196
13197   if (sw_if_index_set == 0)
13198     {
13199       sw_if_index = ~0;
13200     }
13201
13202   if (!vam->json_output)
13203     {
13204       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13205              "sw_if_index", "local", "remote", "vni",
13206              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13207     }
13208
13209   /* Get list of vxlan-tunnel interfaces */
13210   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13211
13212   mp->sw_if_index = htonl (sw_if_index);
13213
13214   S (mp);
13215
13216   /* Use a control ping for synchronization */
13217   MPING (CONTROL_PING, mp_ping);
13218   S (mp_ping);
13219
13220   W (ret);
13221   return ret;
13222 }
13223
13224
13225 u8 *
13226 format_l2_fib_mac_address (u8 * s, va_list * args)
13227 {
13228   u8 *a = va_arg (*args, u8 *);
13229
13230   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13231                  a[2], a[3], a[4], a[5], a[6], a[7]);
13232 }
13233
13234 static void vl_api_l2_fib_table_details_t_handler
13235   (vl_api_l2_fib_table_details_t * mp)
13236 {
13237   vat_main_t *vam = &vat_main;
13238
13239   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13240          "       %d       %d     %d",
13241          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13242          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13243          mp->bvi_mac);
13244 }
13245
13246 static void vl_api_l2_fib_table_details_t_handler_json
13247   (vl_api_l2_fib_table_details_t * mp)
13248 {
13249   vat_main_t *vam = &vat_main;
13250   vat_json_node_t *node = NULL;
13251
13252   if (VAT_JSON_ARRAY != vam->json_tree.type)
13253     {
13254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13255       vat_json_init_array (&vam->json_tree);
13256     }
13257   node = vat_json_array_add (&vam->json_tree);
13258
13259   vat_json_init_object (node);
13260   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13261   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13262   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13263   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13264   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13265   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13266 }
13267
13268 static int
13269 api_l2_fib_table_dump (vat_main_t * vam)
13270 {
13271   unformat_input_t *i = vam->input;
13272   vl_api_l2_fib_table_dump_t *mp;
13273   vl_api_control_ping_t *mp_ping;
13274   u32 bd_id;
13275   u8 bd_id_set = 0;
13276   int ret;
13277
13278   /* Parse args required to build the message */
13279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13280     {
13281       if (unformat (i, "bd_id %d", &bd_id))
13282         bd_id_set = 1;
13283       else
13284         break;
13285     }
13286
13287   if (bd_id_set == 0)
13288     {
13289       errmsg ("missing bridge domain");
13290       return -99;
13291     }
13292
13293   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13294
13295   /* Get list of l2 fib entries */
13296   M (L2_FIB_TABLE_DUMP, mp);
13297
13298   mp->bd_id = ntohl (bd_id);
13299   S (mp);
13300
13301   /* Use a control ping for synchronization */
13302   MPING (CONTROL_PING, mp_ping);
13303   S (mp_ping);
13304
13305   W (ret);
13306   return ret;
13307 }
13308
13309
13310 static int
13311 api_interface_name_renumber (vat_main_t * vam)
13312 {
13313   unformat_input_t *line_input = vam->input;
13314   vl_api_interface_name_renumber_t *mp;
13315   u32 sw_if_index = ~0;
13316   u32 new_show_dev_instance = ~0;
13317   int ret;
13318
13319   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13320     {
13321       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13322                     &sw_if_index))
13323         ;
13324       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13325         ;
13326       else if (unformat (line_input, "new_show_dev_instance %d",
13327                          &new_show_dev_instance))
13328         ;
13329       else
13330         break;
13331     }
13332
13333   if (sw_if_index == ~0)
13334     {
13335       errmsg ("missing interface name or sw_if_index");
13336       return -99;
13337     }
13338
13339   if (new_show_dev_instance == ~0)
13340     {
13341       errmsg ("missing new_show_dev_instance");
13342       return -99;
13343     }
13344
13345   M (INTERFACE_NAME_RENUMBER, mp);
13346
13347   mp->sw_if_index = ntohl (sw_if_index);
13348   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13349
13350   S (mp);
13351   W (ret);
13352   return ret;
13353 }
13354
13355 static int
13356 api_want_ip4_arp_events (vat_main_t * vam)
13357 {
13358   unformat_input_t *line_input = vam->input;
13359   vl_api_want_ip4_arp_events_t *mp;
13360   ip4_address_t address;
13361   int address_set = 0;
13362   u32 enable_disable = 1;
13363   int ret;
13364
13365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13368         address_set = 1;
13369       else if (unformat (line_input, "del"))
13370         enable_disable = 0;
13371       else
13372         break;
13373     }
13374
13375   if (address_set == 0)
13376     {
13377       errmsg ("missing addresses");
13378       return -99;
13379     }
13380
13381   M (WANT_IP4_ARP_EVENTS, mp);
13382   mp->enable_disable = enable_disable;
13383   mp->pid = htonl (getpid ());
13384   mp->address = address.as_u32;
13385
13386   S (mp);
13387   W (ret);
13388   return ret;
13389 }
13390
13391 static int
13392 api_want_ip6_nd_events (vat_main_t * vam)
13393 {
13394   unformat_input_t *line_input = vam->input;
13395   vl_api_want_ip6_nd_events_t *mp;
13396   ip6_address_t address;
13397   int address_set = 0;
13398   u32 enable_disable = 1;
13399   int ret;
13400
13401   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13402     {
13403       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13404         address_set = 1;
13405       else if (unformat (line_input, "del"))
13406         enable_disable = 0;
13407       else
13408         break;
13409     }
13410
13411   if (address_set == 0)
13412     {
13413       errmsg ("missing addresses");
13414       return -99;
13415     }
13416
13417   M (WANT_IP6_ND_EVENTS, mp);
13418   mp->enable_disable = enable_disable;
13419   mp->pid = htonl (getpid ());
13420   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13421
13422   S (mp);
13423   W (ret);
13424   return ret;
13425 }
13426
13427 static int
13428 api_want_l2_macs_events (vat_main_t * vam)
13429 {
13430   unformat_input_t *line_input = vam->input;
13431   vl_api_want_l2_macs_events_t *mp;
13432   u8 enable_disable = 1;
13433   u32 scan_delay = 0;
13434   u32 max_macs_in_event = 0;
13435   u32 learn_limit = 0;
13436   int ret;
13437
13438   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13439     {
13440       if (unformat (line_input, "learn-limit %d", &learn_limit))
13441         ;
13442       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13443         ;
13444       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13445         ;
13446       else if (unformat (line_input, "disable"))
13447         enable_disable = 0;
13448       else
13449         break;
13450     }
13451
13452   M (WANT_L2_MACS_EVENTS, mp);
13453   mp->enable_disable = enable_disable;
13454   mp->pid = htonl (getpid ());
13455   mp->learn_limit = htonl (learn_limit);
13456   mp->scan_delay = (u8) scan_delay;
13457   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13458   S (mp);
13459   W (ret);
13460   return ret;
13461 }
13462
13463 static int
13464 api_input_acl_set_interface (vat_main_t * vam)
13465 {
13466   unformat_input_t *i = vam->input;
13467   vl_api_input_acl_set_interface_t *mp;
13468   u32 sw_if_index;
13469   int sw_if_index_set;
13470   u32 ip4_table_index = ~0;
13471   u32 ip6_table_index = ~0;
13472   u32 l2_table_index = ~0;
13473   u8 is_add = 1;
13474   int ret;
13475
13476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13477     {
13478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13479         sw_if_index_set = 1;
13480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13481         sw_if_index_set = 1;
13482       else if (unformat (i, "del"))
13483         is_add = 0;
13484       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13485         ;
13486       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13487         ;
13488       else if (unformat (i, "l2-table %d", &l2_table_index))
13489         ;
13490       else
13491         {
13492           clib_warning ("parse error '%U'", format_unformat_error, i);
13493           return -99;
13494         }
13495     }
13496
13497   if (sw_if_index_set == 0)
13498     {
13499       errmsg ("missing interface name or sw_if_index");
13500       return -99;
13501     }
13502
13503   M (INPUT_ACL_SET_INTERFACE, mp);
13504
13505   mp->sw_if_index = ntohl (sw_if_index);
13506   mp->ip4_table_index = ntohl (ip4_table_index);
13507   mp->ip6_table_index = ntohl (ip6_table_index);
13508   mp->l2_table_index = ntohl (l2_table_index);
13509   mp->is_add = is_add;
13510
13511   S (mp);
13512   W (ret);
13513   return ret;
13514 }
13515
13516 static int
13517 api_ip_address_dump (vat_main_t * vam)
13518 {
13519   unformat_input_t *i = vam->input;
13520   vl_api_ip_address_dump_t *mp;
13521   vl_api_control_ping_t *mp_ping;
13522   u32 sw_if_index = ~0;
13523   u8 sw_if_index_set = 0;
13524   u8 ipv4_set = 0;
13525   u8 ipv6_set = 0;
13526   int ret;
13527
13528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13529     {
13530       if (unformat (i, "sw_if_index %d", &sw_if_index))
13531         sw_if_index_set = 1;
13532       else
13533         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13534         sw_if_index_set = 1;
13535       else if (unformat (i, "ipv4"))
13536         ipv4_set = 1;
13537       else if (unformat (i, "ipv6"))
13538         ipv6_set = 1;
13539       else
13540         break;
13541     }
13542
13543   if (ipv4_set && ipv6_set)
13544     {
13545       errmsg ("ipv4 and ipv6 flags cannot be both set");
13546       return -99;
13547     }
13548
13549   if ((!ipv4_set) && (!ipv6_set))
13550     {
13551       errmsg ("no ipv4 nor ipv6 flag set");
13552       return -99;
13553     }
13554
13555   if (sw_if_index_set == 0)
13556     {
13557       errmsg ("missing interface name or sw_if_index");
13558       return -99;
13559     }
13560
13561   vam->current_sw_if_index = sw_if_index;
13562   vam->is_ipv6 = ipv6_set;
13563
13564   M (IP_ADDRESS_DUMP, mp);
13565   mp->sw_if_index = ntohl (sw_if_index);
13566   mp->is_ipv6 = ipv6_set;
13567   S (mp);
13568
13569   /* Use a control ping for synchronization */
13570   MPING (CONTROL_PING, mp_ping);
13571   S (mp_ping);
13572
13573   W (ret);
13574   return ret;
13575 }
13576
13577 static int
13578 api_ip_dump (vat_main_t * vam)
13579 {
13580   vl_api_ip_dump_t *mp;
13581   vl_api_control_ping_t *mp_ping;
13582   unformat_input_t *in = vam->input;
13583   int ipv4_set = 0;
13584   int ipv6_set = 0;
13585   int is_ipv6;
13586   int i;
13587   int ret;
13588
13589   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13590     {
13591       if (unformat (in, "ipv4"))
13592         ipv4_set = 1;
13593       else if (unformat (in, "ipv6"))
13594         ipv6_set = 1;
13595       else
13596         break;
13597     }
13598
13599   if (ipv4_set && ipv6_set)
13600     {
13601       errmsg ("ipv4 and ipv6 flags cannot be both set");
13602       return -99;
13603     }
13604
13605   if ((!ipv4_set) && (!ipv6_set))
13606     {
13607       errmsg ("no ipv4 nor ipv6 flag set");
13608       return -99;
13609     }
13610
13611   is_ipv6 = ipv6_set;
13612   vam->is_ipv6 = is_ipv6;
13613
13614   /* free old data */
13615   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13616     {
13617       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13618     }
13619   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13620
13621   M (IP_DUMP, mp);
13622   mp->is_ipv6 = ipv6_set;
13623   S (mp);
13624
13625   /* Use a control ping for synchronization */
13626   MPING (CONTROL_PING, mp_ping);
13627   S (mp_ping);
13628
13629   W (ret);
13630   return ret;
13631 }
13632
13633 static int
13634 api_ipsec_spd_add_del (vat_main_t * vam)
13635 {
13636   unformat_input_t *i = vam->input;
13637   vl_api_ipsec_spd_add_del_t *mp;
13638   u32 spd_id = ~0;
13639   u8 is_add = 1;
13640   int ret;
13641
13642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13643     {
13644       if (unformat (i, "spd_id %d", &spd_id))
13645         ;
13646       else if (unformat (i, "del"))
13647         is_add = 0;
13648       else
13649         {
13650           clib_warning ("parse error '%U'", format_unformat_error, i);
13651           return -99;
13652         }
13653     }
13654   if (spd_id == ~0)
13655     {
13656       errmsg ("spd_id must be set");
13657       return -99;
13658     }
13659
13660   M (IPSEC_SPD_ADD_DEL, mp);
13661
13662   mp->spd_id = ntohl (spd_id);
13663   mp->is_add = is_add;
13664
13665   S (mp);
13666   W (ret);
13667   return ret;
13668 }
13669
13670 static int
13671 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13672 {
13673   unformat_input_t *i = vam->input;
13674   vl_api_ipsec_interface_add_del_spd_t *mp;
13675   u32 sw_if_index;
13676   u8 sw_if_index_set = 0;
13677   u32 spd_id = (u32) ~ 0;
13678   u8 is_add = 1;
13679   int ret;
13680
13681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13682     {
13683       if (unformat (i, "del"))
13684         is_add = 0;
13685       else if (unformat (i, "spd_id %d", &spd_id))
13686         ;
13687       else
13688         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13689         sw_if_index_set = 1;
13690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13691         sw_if_index_set = 1;
13692       else
13693         {
13694           clib_warning ("parse error '%U'", format_unformat_error, i);
13695           return -99;
13696         }
13697
13698     }
13699
13700   if (spd_id == (u32) ~ 0)
13701     {
13702       errmsg ("spd_id must be set");
13703       return -99;
13704     }
13705
13706   if (sw_if_index_set == 0)
13707     {
13708       errmsg ("missing interface name or sw_if_index");
13709       return -99;
13710     }
13711
13712   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13713
13714   mp->spd_id = ntohl (spd_id);
13715   mp->sw_if_index = ntohl (sw_if_index);
13716   mp->is_add = is_add;
13717
13718   S (mp);
13719   W (ret);
13720   return ret;
13721 }
13722
13723 static int
13724 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13725 {
13726   unformat_input_t *i = vam->input;
13727   vl_api_ipsec_spd_add_del_entry_t *mp;
13728   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13729   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13730   i32 priority = 0;
13731   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13732   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13733   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13734   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13735   int ret;
13736
13737   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13738   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13739   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13740   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13741   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13742   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13743
13744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13745     {
13746       if (unformat (i, "del"))
13747         is_add = 0;
13748       if (unformat (i, "outbound"))
13749         is_outbound = 1;
13750       if (unformat (i, "inbound"))
13751         is_outbound = 0;
13752       else if (unformat (i, "spd_id %d", &spd_id))
13753         ;
13754       else if (unformat (i, "sa_id %d", &sa_id))
13755         ;
13756       else if (unformat (i, "priority %d", &priority))
13757         ;
13758       else if (unformat (i, "protocol %d", &protocol))
13759         ;
13760       else if (unformat (i, "lport_start %d", &lport_start))
13761         ;
13762       else if (unformat (i, "lport_stop %d", &lport_stop))
13763         ;
13764       else if (unformat (i, "rport_start %d", &rport_start))
13765         ;
13766       else if (unformat (i, "rport_stop %d", &rport_stop))
13767         ;
13768       else
13769         if (unformat
13770             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13771         {
13772           is_ipv6 = 0;
13773           is_ip_any = 0;
13774         }
13775       else
13776         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13777         {
13778           is_ipv6 = 0;
13779           is_ip_any = 0;
13780         }
13781       else
13782         if (unformat
13783             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13784         {
13785           is_ipv6 = 0;
13786           is_ip_any = 0;
13787         }
13788       else
13789         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13790         {
13791           is_ipv6 = 0;
13792           is_ip_any = 0;
13793         }
13794       else
13795         if (unformat
13796             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13797         {
13798           is_ipv6 = 1;
13799           is_ip_any = 0;
13800         }
13801       else
13802         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13803         {
13804           is_ipv6 = 1;
13805           is_ip_any = 0;
13806         }
13807       else
13808         if (unformat
13809             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13810         {
13811           is_ipv6 = 1;
13812           is_ip_any = 0;
13813         }
13814       else
13815         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13816         {
13817           is_ipv6 = 1;
13818           is_ip_any = 0;
13819         }
13820       else
13821         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13822         {
13823           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13824             {
13825               clib_warning ("unsupported action: 'resolve'");
13826               return -99;
13827             }
13828         }
13829       else
13830         {
13831           clib_warning ("parse error '%U'", format_unformat_error, i);
13832           return -99;
13833         }
13834
13835     }
13836
13837   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13838
13839   mp->spd_id = ntohl (spd_id);
13840   mp->priority = ntohl (priority);
13841   mp->is_outbound = is_outbound;
13842
13843   mp->is_ipv6 = is_ipv6;
13844   if (is_ipv6 || is_ip_any)
13845     {
13846       clib_memcpy (mp->remote_address_start, &raddr6_start,
13847                    sizeof (ip6_address_t));
13848       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13849                    sizeof (ip6_address_t));
13850       clib_memcpy (mp->local_address_start, &laddr6_start,
13851                    sizeof (ip6_address_t));
13852       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13853                    sizeof (ip6_address_t));
13854     }
13855   else
13856     {
13857       clib_memcpy (mp->remote_address_start, &raddr4_start,
13858                    sizeof (ip4_address_t));
13859       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13860                    sizeof (ip4_address_t));
13861       clib_memcpy (mp->local_address_start, &laddr4_start,
13862                    sizeof (ip4_address_t));
13863       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13864                    sizeof (ip4_address_t));
13865     }
13866   mp->protocol = (u8) protocol;
13867   mp->local_port_start = ntohs ((u16) lport_start);
13868   mp->local_port_stop = ntohs ((u16) lport_stop);
13869   mp->remote_port_start = ntohs ((u16) rport_start);
13870   mp->remote_port_stop = ntohs ((u16) rport_stop);
13871   mp->policy = (u8) policy;
13872   mp->sa_id = ntohl (sa_id);
13873   mp->is_add = is_add;
13874   mp->is_ip_any = is_ip_any;
13875   S (mp);
13876   W (ret);
13877   return ret;
13878 }
13879
13880 static int
13881 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13882 {
13883   unformat_input_t *i = vam->input;
13884   vl_api_ipsec_sad_add_del_entry_t *mp;
13885   u32 sad_id = 0, spi = 0;
13886   u8 *ck = 0, *ik = 0;
13887   u8 is_add = 1;
13888
13889   u8 protocol = IPSEC_PROTOCOL_AH;
13890   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13891   u32 crypto_alg = 0, integ_alg = 0;
13892   ip4_address_t tun_src4;
13893   ip4_address_t tun_dst4;
13894   ip6_address_t tun_src6;
13895   ip6_address_t tun_dst6;
13896   int ret;
13897
13898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13899     {
13900       if (unformat (i, "del"))
13901         is_add = 0;
13902       else if (unformat (i, "sad_id %d", &sad_id))
13903         ;
13904       else if (unformat (i, "spi %d", &spi))
13905         ;
13906       else if (unformat (i, "esp"))
13907         protocol = IPSEC_PROTOCOL_ESP;
13908       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13909         {
13910           is_tunnel = 1;
13911           is_tunnel_ipv6 = 0;
13912         }
13913       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13914         {
13915           is_tunnel = 1;
13916           is_tunnel_ipv6 = 0;
13917         }
13918       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13919         {
13920           is_tunnel = 1;
13921           is_tunnel_ipv6 = 1;
13922         }
13923       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13924         {
13925           is_tunnel = 1;
13926           is_tunnel_ipv6 = 1;
13927         }
13928       else
13929         if (unformat
13930             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13931         {
13932           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13933               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13934             {
13935               clib_warning ("unsupported crypto-alg: '%U'",
13936                             format_ipsec_crypto_alg, crypto_alg);
13937               return -99;
13938             }
13939         }
13940       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13941         ;
13942       else
13943         if (unformat
13944             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13945         {
13946           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13947               integ_alg >= IPSEC_INTEG_N_ALG)
13948             {
13949               clib_warning ("unsupported integ-alg: '%U'",
13950                             format_ipsec_integ_alg, integ_alg);
13951               return -99;
13952             }
13953         }
13954       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13955         ;
13956       else
13957         {
13958           clib_warning ("parse error '%U'", format_unformat_error, i);
13959           return -99;
13960         }
13961
13962     }
13963
13964   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13965
13966   mp->sad_id = ntohl (sad_id);
13967   mp->is_add = is_add;
13968   mp->protocol = protocol;
13969   mp->spi = ntohl (spi);
13970   mp->is_tunnel = is_tunnel;
13971   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13972   mp->crypto_algorithm = crypto_alg;
13973   mp->integrity_algorithm = integ_alg;
13974   mp->crypto_key_length = vec_len (ck);
13975   mp->integrity_key_length = vec_len (ik);
13976
13977   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13978     mp->crypto_key_length = sizeof (mp->crypto_key);
13979
13980   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13981     mp->integrity_key_length = sizeof (mp->integrity_key);
13982
13983   if (ck)
13984     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13985   if (ik)
13986     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13987
13988   if (is_tunnel)
13989     {
13990       if (is_tunnel_ipv6)
13991         {
13992           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13993                        sizeof (ip6_address_t));
13994           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13995                        sizeof (ip6_address_t));
13996         }
13997       else
13998         {
13999           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14000                        sizeof (ip4_address_t));
14001           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14002                        sizeof (ip4_address_t));
14003         }
14004     }
14005
14006   S (mp);
14007   W (ret);
14008   return ret;
14009 }
14010
14011 static int
14012 api_ipsec_sa_set_key (vat_main_t * vam)
14013 {
14014   unformat_input_t *i = vam->input;
14015   vl_api_ipsec_sa_set_key_t *mp;
14016   u32 sa_id;
14017   u8 *ck = 0, *ik = 0;
14018   int ret;
14019
14020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14021     {
14022       if (unformat (i, "sa_id %d", &sa_id))
14023         ;
14024       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14025         ;
14026       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14027         ;
14028       else
14029         {
14030           clib_warning ("parse error '%U'", format_unformat_error, i);
14031           return -99;
14032         }
14033     }
14034
14035   M (IPSEC_SA_SET_KEY, mp);
14036
14037   mp->sa_id = ntohl (sa_id);
14038   mp->crypto_key_length = vec_len (ck);
14039   mp->integrity_key_length = vec_len (ik);
14040
14041   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14042     mp->crypto_key_length = sizeof (mp->crypto_key);
14043
14044   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14045     mp->integrity_key_length = sizeof (mp->integrity_key);
14046
14047   if (ck)
14048     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14049   if (ik)
14050     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14051
14052   S (mp);
14053   W (ret);
14054   return ret;
14055 }
14056
14057 static int
14058 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14059 {
14060   unformat_input_t *i = vam->input;
14061   vl_api_ipsec_tunnel_if_add_del_t *mp;
14062   u32 local_spi = 0, remote_spi = 0;
14063   u32 crypto_alg = 0, integ_alg = 0;
14064   u8 *lck = NULL, *rck = NULL;
14065   u8 *lik = NULL, *rik = NULL;
14066   ip4_address_t local_ip = { {0} };
14067   ip4_address_t remote_ip = { {0} };
14068   u8 is_add = 1;
14069   u8 esn = 0;
14070   u8 anti_replay = 0;
14071   int ret;
14072
14073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14074     {
14075       if (unformat (i, "del"))
14076         is_add = 0;
14077       else if (unformat (i, "esn"))
14078         esn = 1;
14079       else if (unformat (i, "anti_replay"))
14080         anti_replay = 1;
14081       else if (unformat (i, "local_spi %d", &local_spi))
14082         ;
14083       else if (unformat (i, "remote_spi %d", &remote_spi))
14084         ;
14085       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14086         ;
14087       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14088         ;
14089       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14090         ;
14091       else
14092         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14093         ;
14094       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14095         ;
14096       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14097         ;
14098       else
14099         if (unformat
14100             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14101         {
14102           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14103               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14104             {
14105               errmsg ("unsupported crypto-alg: '%U'\n",
14106                       format_ipsec_crypto_alg, crypto_alg);
14107               return -99;
14108             }
14109         }
14110       else
14111         if (unformat
14112             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14113         {
14114           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14115               integ_alg >= IPSEC_INTEG_N_ALG)
14116             {
14117               errmsg ("unsupported integ-alg: '%U'\n",
14118                       format_ipsec_integ_alg, integ_alg);
14119               return -99;
14120             }
14121         }
14122       else
14123         {
14124           errmsg ("parse error '%U'\n", format_unformat_error, i);
14125           return -99;
14126         }
14127     }
14128
14129   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14130
14131   mp->is_add = is_add;
14132   mp->esn = esn;
14133   mp->anti_replay = anti_replay;
14134
14135   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14136   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14137
14138   mp->local_spi = htonl (local_spi);
14139   mp->remote_spi = htonl (remote_spi);
14140   mp->crypto_alg = (u8) crypto_alg;
14141
14142   mp->local_crypto_key_len = 0;
14143   if (lck)
14144     {
14145       mp->local_crypto_key_len = vec_len (lck);
14146       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14147         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14148       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14149     }
14150
14151   mp->remote_crypto_key_len = 0;
14152   if (rck)
14153     {
14154       mp->remote_crypto_key_len = vec_len (rck);
14155       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14156         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14157       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14158     }
14159
14160   mp->integ_alg = (u8) integ_alg;
14161
14162   mp->local_integ_key_len = 0;
14163   if (lik)
14164     {
14165       mp->local_integ_key_len = vec_len (lik);
14166       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14167         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14168       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14169     }
14170
14171   mp->remote_integ_key_len = 0;
14172   if (rik)
14173     {
14174       mp->remote_integ_key_len = vec_len (rik);
14175       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14176         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14177       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14178     }
14179
14180   S (mp);
14181   W (ret);
14182   return ret;
14183 }
14184
14185 static void
14186 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14187 {
14188   vat_main_t *vam = &vat_main;
14189
14190   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14191          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14192          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14193          "tunnel_src_addr %U tunnel_dst_addr %U "
14194          "salt %u seq_outbound %lu last_seq_inbound %lu "
14195          "replay_window %lu total_data_size %lu\n",
14196          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14197          mp->protocol,
14198          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14199          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14200          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14201          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14202          mp->tunnel_src_addr,
14203          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14204          mp->tunnel_dst_addr,
14205          ntohl (mp->salt),
14206          clib_net_to_host_u64 (mp->seq_outbound),
14207          clib_net_to_host_u64 (mp->last_seq_inbound),
14208          clib_net_to_host_u64 (mp->replay_window),
14209          clib_net_to_host_u64 (mp->total_data_size));
14210 }
14211
14212 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14213 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14214
14215 static void vl_api_ipsec_sa_details_t_handler_json
14216   (vl_api_ipsec_sa_details_t * mp)
14217 {
14218   vat_main_t *vam = &vat_main;
14219   vat_json_node_t *node = NULL;
14220   struct in_addr src_ip4, dst_ip4;
14221   struct in6_addr src_ip6, dst_ip6;
14222
14223   if (VAT_JSON_ARRAY != vam->json_tree.type)
14224     {
14225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14226       vat_json_init_array (&vam->json_tree);
14227     }
14228   node = vat_json_array_add (&vam->json_tree);
14229
14230   vat_json_init_object (node);
14231   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14232   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14233   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14234   vat_json_object_add_uint (node, "proto", mp->protocol);
14235   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14236   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14237   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14238   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14239   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14240   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14241   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14242                              mp->crypto_key_len);
14243   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14244                              mp->integ_key_len);
14245   if (mp->is_tunnel_ip6)
14246     {
14247       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14248       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14249       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14250       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14251     }
14252   else
14253     {
14254       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14255       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14256       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14257       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14258     }
14259   vat_json_object_add_uint (node, "replay_window",
14260                             clib_net_to_host_u64 (mp->replay_window));
14261   vat_json_object_add_uint (node, "total_data_size",
14262                             clib_net_to_host_u64 (mp->total_data_size));
14263
14264 }
14265
14266 static int
14267 api_ipsec_sa_dump (vat_main_t * vam)
14268 {
14269   unformat_input_t *i = vam->input;
14270   vl_api_ipsec_sa_dump_t *mp;
14271   vl_api_control_ping_t *mp_ping;
14272   u32 sa_id = ~0;
14273   int ret;
14274
14275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14276     {
14277       if (unformat (i, "sa_id %d", &sa_id))
14278         ;
14279       else
14280         {
14281           clib_warning ("parse error '%U'", format_unformat_error, i);
14282           return -99;
14283         }
14284     }
14285
14286   M (IPSEC_SA_DUMP, mp);
14287
14288   mp->sa_id = ntohl (sa_id);
14289
14290   S (mp);
14291
14292   /* Use a control ping for synchronization */
14293   M (CONTROL_PING, mp_ping);
14294   S (mp_ping);
14295
14296   W (ret);
14297   return ret;
14298 }
14299
14300 static int
14301 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14302 {
14303   unformat_input_t *i = vam->input;
14304   vl_api_ipsec_tunnel_if_set_key_t *mp;
14305   u32 sw_if_index = ~0;
14306   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14307   u8 *key = 0;
14308   u32 alg = ~0;
14309   int ret;
14310
14311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14314         ;
14315       else
14316         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14317         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14318       else
14319         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14320         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14321       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14322         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14323       else
14324         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14325         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14326       else if (unformat (i, "%U", unformat_hex_string, &key))
14327         ;
14328       else
14329         {
14330           clib_warning ("parse error '%U'", format_unformat_error, i);
14331           return -99;
14332         }
14333     }
14334
14335   if (sw_if_index == ~0)
14336     {
14337       errmsg ("interface must be specified");
14338       return -99;
14339     }
14340
14341   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14342     {
14343       errmsg ("key type must be specified");
14344       return -99;
14345     }
14346
14347   if (alg == ~0)
14348     {
14349       errmsg ("algorithm must be specified");
14350       return -99;
14351     }
14352
14353   if (vec_len (key) == 0)
14354     {
14355       errmsg ("key must be specified");
14356       return -99;
14357     }
14358
14359   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14360
14361   mp->sw_if_index = htonl (sw_if_index);
14362   mp->alg = alg;
14363   mp->key_type = key_type;
14364   mp->key_len = vec_len (key);
14365   clib_memcpy (mp->key, key, vec_len (key));
14366
14367   S (mp);
14368   W (ret);
14369
14370   return ret;
14371 }
14372
14373 static int
14374 api_ikev2_profile_add_del (vat_main_t * vam)
14375 {
14376   unformat_input_t *i = vam->input;
14377   vl_api_ikev2_profile_add_del_t *mp;
14378   u8 is_add = 1;
14379   u8 *name = 0;
14380   int ret;
14381
14382   const char *valid_chars = "a-zA-Z0-9_";
14383
14384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14385     {
14386       if (unformat (i, "del"))
14387         is_add = 0;
14388       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14389         vec_add1 (name, 0);
14390       else
14391         {
14392           errmsg ("parse error '%U'", format_unformat_error, i);
14393           return -99;
14394         }
14395     }
14396
14397   if (!vec_len (name))
14398     {
14399       errmsg ("profile name must be specified");
14400       return -99;
14401     }
14402
14403   if (vec_len (name) > 64)
14404     {
14405       errmsg ("profile name too long");
14406       return -99;
14407     }
14408
14409   M (IKEV2_PROFILE_ADD_DEL, mp);
14410
14411   clib_memcpy (mp->name, name, vec_len (name));
14412   mp->is_add = is_add;
14413   vec_free (name);
14414
14415   S (mp);
14416   W (ret);
14417   return ret;
14418 }
14419
14420 static int
14421 api_ikev2_profile_set_auth (vat_main_t * vam)
14422 {
14423   unformat_input_t *i = vam->input;
14424   vl_api_ikev2_profile_set_auth_t *mp;
14425   u8 *name = 0;
14426   u8 *data = 0;
14427   u32 auth_method = 0;
14428   u8 is_hex = 0;
14429   int ret;
14430
14431   const char *valid_chars = "a-zA-Z0-9_";
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14436         vec_add1 (name, 0);
14437       else if (unformat (i, "auth_method %U",
14438                          unformat_ikev2_auth_method, &auth_method))
14439         ;
14440       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14441         is_hex = 1;
14442       else if (unformat (i, "auth_data %v", &data))
14443         ;
14444       else
14445         {
14446           errmsg ("parse error '%U'", format_unformat_error, i);
14447           return -99;
14448         }
14449     }
14450
14451   if (!vec_len (name))
14452     {
14453       errmsg ("profile name must be specified");
14454       return -99;
14455     }
14456
14457   if (vec_len (name) > 64)
14458     {
14459       errmsg ("profile name too long");
14460       return -99;
14461     }
14462
14463   if (!vec_len (data))
14464     {
14465       errmsg ("auth_data must be specified");
14466       return -99;
14467     }
14468
14469   if (!auth_method)
14470     {
14471       errmsg ("auth_method must be specified");
14472       return -99;
14473     }
14474
14475   M (IKEV2_PROFILE_SET_AUTH, mp);
14476
14477   mp->is_hex = is_hex;
14478   mp->auth_method = (u8) auth_method;
14479   mp->data_len = vec_len (data);
14480   clib_memcpy (mp->name, name, vec_len (name));
14481   clib_memcpy (mp->data, data, vec_len (data));
14482   vec_free (name);
14483   vec_free (data);
14484
14485   S (mp);
14486   W (ret);
14487   return ret;
14488 }
14489
14490 static int
14491 api_ikev2_profile_set_id (vat_main_t * vam)
14492 {
14493   unformat_input_t *i = vam->input;
14494   vl_api_ikev2_profile_set_id_t *mp;
14495   u8 *name = 0;
14496   u8 *data = 0;
14497   u8 is_local = 0;
14498   u32 id_type = 0;
14499   ip4_address_t ip4;
14500   int ret;
14501
14502   const char *valid_chars = "a-zA-Z0-9_";
14503
14504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14505     {
14506       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14507         vec_add1 (name, 0);
14508       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14509         ;
14510       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14511         {
14512           data = vec_new (u8, 4);
14513           clib_memcpy (data, ip4.as_u8, 4);
14514         }
14515       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14516         ;
14517       else if (unformat (i, "id_data %v", &data))
14518         ;
14519       else if (unformat (i, "local"))
14520         is_local = 1;
14521       else if (unformat (i, "remote"))
14522         is_local = 0;
14523       else
14524         {
14525           errmsg ("parse error '%U'", format_unformat_error, i);
14526           return -99;
14527         }
14528     }
14529
14530   if (!vec_len (name))
14531     {
14532       errmsg ("profile name must be specified");
14533       return -99;
14534     }
14535
14536   if (vec_len (name) > 64)
14537     {
14538       errmsg ("profile name too long");
14539       return -99;
14540     }
14541
14542   if (!vec_len (data))
14543     {
14544       errmsg ("id_data must be specified");
14545       return -99;
14546     }
14547
14548   if (!id_type)
14549     {
14550       errmsg ("id_type must be specified");
14551       return -99;
14552     }
14553
14554   M (IKEV2_PROFILE_SET_ID, mp);
14555
14556   mp->is_local = is_local;
14557   mp->id_type = (u8) id_type;
14558   mp->data_len = vec_len (data);
14559   clib_memcpy (mp->name, name, vec_len (name));
14560   clib_memcpy (mp->data, data, vec_len (data));
14561   vec_free (name);
14562   vec_free (data);
14563
14564   S (mp);
14565   W (ret);
14566   return ret;
14567 }
14568
14569 static int
14570 api_ikev2_profile_set_ts (vat_main_t * vam)
14571 {
14572   unformat_input_t *i = vam->input;
14573   vl_api_ikev2_profile_set_ts_t *mp;
14574   u8 *name = 0;
14575   u8 is_local = 0;
14576   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14577   ip4_address_t start_addr, end_addr;
14578
14579   const char *valid_chars = "a-zA-Z0-9_";
14580   int ret;
14581
14582   start_addr.as_u32 = 0;
14583   end_addr.as_u32 = (u32) ~ 0;
14584
14585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14586     {
14587       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14588         vec_add1 (name, 0);
14589       else if (unformat (i, "protocol %d", &proto))
14590         ;
14591       else if (unformat (i, "start_port %d", &start_port))
14592         ;
14593       else if (unformat (i, "end_port %d", &end_port))
14594         ;
14595       else
14596         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14597         ;
14598       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14599         ;
14600       else if (unformat (i, "local"))
14601         is_local = 1;
14602       else if (unformat (i, "remote"))
14603         is_local = 0;
14604       else
14605         {
14606           errmsg ("parse error '%U'", format_unformat_error, i);
14607           return -99;
14608         }
14609     }
14610
14611   if (!vec_len (name))
14612     {
14613       errmsg ("profile name must be specified");
14614       return -99;
14615     }
14616
14617   if (vec_len (name) > 64)
14618     {
14619       errmsg ("profile name too long");
14620       return -99;
14621     }
14622
14623   M (IKEV2_PROFILE_SET_TS, mp);
14624
14625   mp->is_local = is_local;
14626   mp->proto = (u8) proto;
14627   mp->start_port = (u16) start_port;
14628   mp->end_port = (u16) end_port;
14629   mp->start_addr = start_addr.as_u32;
14630   mp->end_addr = end_addr.as_u32;
14631   clib_memcpy (mp->name, name, vec_len (name));
14632   vec_free (name);
14633
14634   S (mp);
14635   W (ret);
14636   return ret;
14637 }
14638
14639 static int
14640 api_ikev2_set_local_key (vat_main_t * vam)
14641 {
14642   unformat_input_t *i = vam->input;
14643   vl_api_ikev2_set_local_key_t *mp;
14644   u8 *file = 0;
14645   int ret;
14646
14647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14648     {
14649       if (unformat (i, "file %v", &file))
14650         vec_add1 (file, 0);
14651       else
14652         {
14653           errmsg ("parse error '%U'", format_unformat_error, i);
14654           return -99;
14655         }
14656     }
14657
14658   if (!vec_len (file))
14659     {
14660       errmsg ("RSA key file must be specified");
14661       return -99;
14662     }
14663
14664   if (vec_len (file) > 256)
14665     {
14666       errmsg ("file name too long");
14667       return -99;
14668     }
14669
14670   M (IKEV2_SET_LOCAL_KEY, mp);
14671
14672   clib_memcpy (mp->key_file, file, vec_len (file));
14673   vec_free (file);
14674
14675   S (mp);
14676   W (ret);
14677   return ret;
14678 }
14679
14680 static int
14681 api_ikev2_set_responder (vat_main_t * vam)
14682 {
14683   unformat_input_t *i = vam->input;
14684   vl_api_ikev2_set_responder_t *mp;
14685   int ret;
14686   u8 *name = 0;
14687   u32 sw_if_index = ~0;
14688   ip4_address_t address;
14689
14690   const char *valid_chars = "a-zA-Z0-9_";
14691
14692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14693     {
14694       if (unformat
14695           (i, "%U interface %d address %U", unformat_token, valid_chars,
14696            &name, &sw_if_index, unformat_ip4_address, &address))
14697         vec_add1 (name, 0);
14698       else
14699         {
14700           errmsg ("parse error '%U'", format_unformat_error, i);
14701           return -99;
14702         }
14703     }
14704
14705   if (!vec_len (name))
14706     {
14707       errmsg ("profile name must be specified");
14708       return -99;
14709     }
14710
14711   if (vec_len (name) > 64)
14712     {
14713       errmsg ("profile name too long");
14714       return -99;
14715     }
14716
14717   M (IKEV2_SET_RESPONDER, mp);
14718
14719   clib_memcpy (mp->name, name, vec_len (name));
14720   vec_free (name);
14721
14722   mp->sw_if_index = sw_if_index;
14723   clib_memcpy (mp->address, &address, sizeof (address));
14724
14725   S (mp);
14726   W (ret);
14727   return ret;
14728 }
14729
14730 static int
14731 api_ikev2_set_ike_transforms (vat_main_t * vam)
14732 {
14733   unformat_input_t *i = vam->input;
14734   vl_api_ikev2_set_ike_transforms_t *mp;
14735   int ret;
14736   u8 *name = 0;
14737   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14738
14739   const char *valid_chars = "a-zA-Z0-9_";
14740
14741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14742     {
14743       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14744                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14745         vec_add1 (name, 0);
14746       else
14747         {
14748           errmsg ("parse error '%U'", format_unformat_error, i);
14749           return -99;
14750         }
14751     }
14752
14753   if (!vec_len (name))
14754     {
14755       errmsg ("profile name must be specified");
14756       return -99;
14757     }
14758
14759   if (vec_len (name) > 64)
14760     {
14761       errmsg ("profile name too long");
14762       return -99;
14763     }
14764
14765   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14766
14767   clib_memcpy (mp->name, name, vec_len (name));
14768   vec_free (name);
14769   mp->crypto_alg = crypto_alg;
14770   mp->crypto_key_size = crypto_key_size;
14771   mp->integ_alg = integ_alg;
14772   mp->dh_group = dh_group;
14773
14774   S (mp);
14775   W (ret);
14776   return ret;
14777 }
14778
14779
14780 static int
14781 api_ikev2_set_esp_transforms (vat_main_t * vam)
14782 {
14783   unformat_input_t *i = vam->input;
14784   vl_api_ikev2_set_esp_transforms_t *mp;
14785   int ret;
14786   u8 *name = 0;
14787   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14788
14789   const char *valid_chars = "a-zA-Z0-9_";
14790
14791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14792     {
14793       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14794                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14795         vec_add1 (name, 0);
14796       else
14797         {
14798           errmsg ("parse error '%U'", format_unformat_error, i);
14799           return -99;
14800         }
14801     }
14802
14803   if (!vec_len (name))
14804     {
14805       errmsg ("profile name must be specified");
14806       return -99;
14807     }
14808
14809   if (vec_len (name) > 64)
14810     {
14811       errmsg ("profile name too long");
14812       return -99;
14813     }
14814
14815   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14816
14817   clib_memcpy (mp->name, name, vec_len (name));
14818   vec_free (name);
14819   mp->crypto_alg = crypto_alg;
14820   mp->crypto_key_size = crypto_key_size;
14821   mp->integ_alg = integ_alg;
14822   mp->dh_group = dh_group;
14823
14824   S (mp);
14825   W (ret);
14826   return ret;
14827 }
14828
14829 static int
14830 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14831 {
14832   unformat_input_t *i = vam->input;
14833   vl_api_ikev2_set_sa_lifetime_t *mp;
14834   int ret;
14835   u8 *name = 0;
14836   u64 lifetime, lifetime_maxdata;
14837   u32 lifetime_jitter, handover;
14838
14839   const char *valid_chars = "a-zA-Z0-9_";
14840
14841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14844                     &lifetime, &lifetime_jitter, &handover,
14845                     &lifetime_maxdata))
14846         vec_add1 (name, 0);
14847       else
14848         {
14849           errmsg ("parse error '%U'", format_unformat_error, i);
14850           return -99;
14851         }
14852     }
14853
14854   if (!vec_len (name))
14855     {
14856       errmsg ("profile name must be specified");
14857       return -99;
14858     }
14859
14860   if (vec_len (name) > 64)
14861     {
14862       errmsg ("profile name too long");
14863       return -99;
14864     }
14865
14866   M (IKEV2_SET_SA_LIFETIME, mp);
14867
14868   clib_memcpy (mp->name, name, vec_len (name));
14869   vec_free (name);
14870   mp->lifetime = lifetime;
14871   mp->lifetime_jitter = lifetime_jitter;
14872   mp->handover = handover;
14873   mp->lifetime_maxdata = lifetime_maxdata;
14874
14875   S (mp);
14876   W (ret);
14877   return ret;
14878 }
14879
14880 static int
14881 api_ikev2_initiate_sa_init (vat_main_t * vam)
14882 {
14883   unformat_input_t *i = vam->input;
14884   vl_api_ikev2_initiate_sa_init_t *mp;
14885   int ret;
14886   u8 *name = 0;
14887
14888   const char *valid_chars = "a-zA-Z0-9_";
14889
14890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14891     {
14892       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14893         vec_add1 (name, 0);
14894       else
14895         {
14896           errmsg ("parse error '%U'", format_unformat_error, i);
14897           return -99;
14898         }
14899     }
14900
14901   if (!vec_len (name))
14902     {
14903       errmsg ("profile name must be specified");
14904       return -99;
14905     }
14906
14907   if (vec_len (name) > 64)
14908     {
14909       errmsg ("profile name too long");
14910       return -99;
14911     }
14912
14913   M (IKEV2_INITIATE_SA_INIT, mp);
14914
14915   clib_memcpy (mp->name, name, vec_len (name));
14916   vec_free (name);
14917
14918   S (mp);
14919   W (ret);
14920   return ret;
14921 }
14922
14923 static int
14924 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14925 {
14926   unformat_input_t *i = vam->input;
14927   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14928   int ret;
14929   u64 ispi;
14930
14931
14932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14933     {
14934       if (unformat (i, "%lx", &ispi))
14935         ;
14936       else
14937         {
14938           errmsg ("parse error '%U'", format_unformat_error, i);
14939           return -99;
14940         }
14941     }
14942
14943   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14944
14945   mp->ispi = ispi;
14946
14947   S (mp);
14948   W (ret);
14949   return ret;
14950 }
14951
14952 static int
14953 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14954 {
14955   unformat_input_t *i = vam->input;
14956   vl_api_ikev2_initiate_del_child_sa_t *mp;
14957   int ret;
14958   u32 ispi;
14959
14960
14961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (i, "%x", &ispi))
14964         ;
14965       else
14966         {
14967           errmsg ("parse error '%U'", format_unformat_error, i);
14968           return -99;
14969         }
14970     }
14971
14972   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14973
14974   mp->ispi = ispi;
14975
14976   S (mp);
14977   W (ret);
14978   return ret;
14979 }
14980
14981 static int
14982 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14983 {
14984   unformat_input_t *i = vam->input;
14985   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14986   int ret;
14987   u32 ispi;
14988
14989
14990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14991     {
14992       if (unformat (i, "%x", &ispi))
14993         ;
14994       else
14995         {
14996           errmsg ("parse error '%U'", format_unformat_error, i);
14997           return -99;
14998         }
14999     }
15000
15001   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15002
15003   mp->ispi = ispi;
15004
15005   S (mp);
15006   W (ret);
15007   return ret;
15008 }
15009
15010 /*
15011  * MAP
15012  */
15013 static int
15014 api_map_add_domain (vat_main_t * vam)
15015 {
15016   unformat_input_t *i = vam->input;
15017   vl_api_map_add_domain_t *mp;
15018
15019   ip4_address_t ip4_prefix;
15020   ip6_address_t ip6_prefix;
15021   ip6_address_t ip6_src;
15022   u32 num_m_args = 0;
15023   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15024     0, psid_length = 0;
15025   u8 is_translation = 0;
15026   u32 mtu = 0;
15027   u32 ip6_src_len = 128;
15028   int ret;
15029
15030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15031     {
15032       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15033                     &ip4_prefix, &ip4_prefix_len))
15034         num_m_args++;
15035       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15036                          &ip6_prefix, &ip6_prefix_len))
15037         num_m_args++;
15038       else
15039         if (unformat
15040             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15041              &ip6_src_len))
15042         num_m_args++;
15043       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15044         num_m_args++;
15045       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15046         num_m_args++;
15047       else if (unformat (i, "psid-offset %d", &psid_offset))
15048         num_m_args++;
15049       else if (unformat (i, "psid-len %d", &psid_length))
15050         num_m_args++;
15051       else if (unformat (i, "mtu %d", &mtu))
15052         num_m_args++;
15053       else if (unformat (i, "map-t"))
15054         is_translation = 1;
15055       else
15056         {
15057           clib_warning ("parse error '%U'", format_unformat_error, i);
15058           return -99;
15059         }
15060     }
15061
15062   if (num_m_args < 3)
15063     {
15064       errmsg ("mandatory argument(s) missing");
15065       return -99;
15066     }
15067
15068   /* Construct the API message */
15069   M (MAP_ADD_DOMAIN, mp);
15070
15071   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15072   mp->ip4_prefix_len = ip4_prefix_len;
15073
15074   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15075   mp->ip6_prefix_len = ip6_prefix_len;
15076
15077   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15078   mp->ip6_src_prefix_len = ip6_src_len;
15079
15080   mp->ea_bits_len = ea_bits_len;
15081   mp->psid_offset = psid_offset;
15082   mp->psid_length = psid_length;
15083   mp->is_translation = is_translation;
15084   mp->mtu = htons (mtu);
15085
15086   /* send it... */
15087   S (mp);
15088
15089   /* Wait for a reply, return good/bad news  */
15090   W (ret);
15091   return ret;
15092 }
15093
15094 static int
15095 api_map_del_domain (vat_main_t * vam)
15096 {
15097   unformat_input_t *i = vam->input;
15098   vl_api_map_del_domain_t *mp;
15099
15100   u32 num_m_args = 0;
15101   u32 index;
15102   int ret;
15103
15104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15105     {
15106       if (unformat (i, "index %d", &index))
15107         num_m_args++;
15108       else
15109         {
15110           clib_warning ("parse error '%U'", format_unformat_error, i);
15111           return -99;
15112         }
15113     }
15114
15115   if (num_m_args != 1)
15116     {
15117       errmsg ("mandatory argument(s) missing");
15118       return -99;
15119     }
15120
15121   /* Construct the API message */
15122   M (MAP_DEL_DOMAIN, mp);
15123
15124   mp->index = ntohl (index);
15125
15126   /* send it... */
15127   S (mp);
15128
15129   /* Wait for a reply, return good/bad news  */
15130   W (ret);
15131   return ret;
15132 }
15133
15134 static int
15135 api_map_add_del_rule (vat_main_t * vam)
15136 {
15137   unformat_input_t *i = vam->input;
15138   vl_api_map_add_del_rule_t *mp;
15139   u8 is_add = 1;
15140   ip6_address_t ip6_dst;
15141   u32 num_m_args = 0, index, psid = 0;
15142   int ret;
15143
15144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15145     {
15146       if (unformat (i, "index %d", &index))
15147         num_m_args++;
15148       else if (unformat (i, "psid %d", &psid))
15149         num_m_args++;
15150       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15151         num_m_args++;
15152       else if (unformat (i, "del"))
15153         {
15154           is_add = 0;
15155         }
15156       else
15157         {
15158           clib_warning ("parse error '%U'", format_unformat_error, i);
15159           return -99;
15160         }
15161     }
15162
15163   /* Construct the API message */
15164   M (MAP_ADD_DEL_RULE, mp);
15165
15166   mp->index = ntohl (index);
15167   mp->is_add = is_add;
15168   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15169   mp->psid = ntohs (psid);
15170
15171   /* send it... */
15172   S (mp);
15173
15174   /* Wait for a reply, return good/bad news  */
15175   W (ret);
15176   return ret;
15177 }
15178
15179 static int
15180 api_map_domain_dump (vat_main_t * vam)
15181 {
15182   vl_api_map_domain_dump_t *mp;
15183   vl_api_control_ping_t *mp_ping;
15184   int ret;
15185
15186   /* Construct the API message */
15187   M (MAP_DOMAIN_DUMP, mp);
15188
15189   /* send it... */
15190   S (mp);
15191
15192   /* Use a control ping for synchronization */
15193   MPING (CONTROL_PING, mp_ping);
15194   S (mp_ping);
15195
15196   W (ret);
15197   return ret;
15198 }
15199
15200 static int
15201 api_map_rule_dump (vat_main_t * vam)
15202 {
15203   unformat_input_t *i = vam->input;
15204   vl_api_map_rule_dump_t *mp;
15205   vl_api_control_ping_t *mp_ping;
15206   u32 domain_index = ~0;
15207   int ret;
15208
15209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15210     {
15211       if (unformat (i, "index %u", &domain_index))
15212         ;
15213       else
15214         break;
15215     }
15216
15217   if (domain_index == ~0)
15218     {
15219       clib_warning ("parse error: domain index expected");
15220       return -99;
15221     }
15222
15223   /* Construct the API message */
15224   M (MAP_RULE_DUMP, mp);
15225
15226   mp->domain_index = htonl (domain_index);
15227
15228   /* send it... */
15229   S (mp);
15230
15231   /* Use a control ping for synchronization */
15232   MPING (CONTROL_PING, mp_ping);
15233   S (mp_ping);
15234
15235   W (ret);
15236   return ret;
15237 }
15238
15239 static void vl_api_map_add_domain_reply_t_handler
15240   (vl_api_map_add_domain_reply_t * mp)
15241 {
15242   vat_main_t *vam = &vat_main;
15243   i32 retval = ntohl (mp->retval);
15244
15245   if (vam->async_mode)
15246     {
15247       vam->async_errors += (retval < 0);
15248     }
15249   else
15250     {
15251       vam->retval = retval;
15252       vam->result_ready = 1;
15253     }
15254 }
15255
15256 static void vl_api_map_add_domain_reply_t_handler_json
15257   (vl_api_map_add_domain_reply_t * mp)
15258 {
15259   vat_main_t *vam = &vat_main;
15260   vat_json_node_t node;
15261
15262   vat_json_init_object (&node);
15263   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15264   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15265
15266   vat_json_print (vam->ofp, &node);
15267   vat_json_free (&node);
15268
15269   vam->retval = ntohl (mp->retval);
15270   vam->result_ready = 1;
15271 }
15272
15273 static int
15274 api_get_first_msg_id (vat_main_t * vam)
15275 {
15276   vl_api_get_first_msg_id_t *mp;
15277   unformat_input_t *i = vam->input;
15278   u8 *name;
15279   u8 name_set = 0;
15280   int ret;
15281
15282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15283     {
15284       if (unformat (i, "client %s", &name))
15285         name_set = 1;
15286       else
15287         break;
15288     }
15289
15290   if (name_set == 0)
15291     {
15292       errmsg ("missing client name");
15293       return -99;
15294     }
15295   vec_add1 (name, 0);
15296
15297   if (vec_len (name) > 63)
15298     {
15299       errmsg ("client name too long");
15300       return -99;
15301     }
15302
15303   M (GET_FIRST_MSG_ID, mp);
15304   clib_memcpy (mp->name, name, vec_len (name));
15305   S (mp);
15306   W (ret);
15307   return ret;
15308 }
15309
15310 static int
15311 api_cop_interface_enable_disable (vat_main_t * vam)
15312 {
15313   unformat_input_t *line_input = vam->input;
15314   vl_api_cop_interface_enable_disable_t *mp;
15315   u32 sw_if_index = ~0;
15316   u8 enable_disable = 1;
15317   int ret;
15318
15319   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15320     {
15321       if (unformat (line_input, "disable"))
15322         enable_disable = 0;
15323       if (unformat (line_input, "enable"))
15324         enable_disable = 1;
15325       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15326                          vam, &sw_if_index))
15327         ;
15328       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15329         ;
15330       else
15331         break;
15332     }
15333
15334   if (sw_if_index == ~0)
15335     {
15336       errmsg ("missing interface name or sw_if_index");
15337       return -99;
15338     }
15339
15340   /* Construct the API message */
15341   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15342   mp->sw_if_index = ntohl (sw_if_index);
15343   mp->enable_disable = enable_disable;
15344
15345   /* send it... */
15346   S (mp);
15347   /* Wait for the reply */
15348   W (ret);
15349   return ret;
15350 }
15351
15352 static int
15353 api_cop_whitelist_enable_disable (vat_main_t * vam)
15354 {
15355   unformat_input_t *line_input = vam->input;
15356   vl_api_cop_whitelist_enable_disable_t *mp;
15357   u32 sw_if_index = ~0;
15358   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15359   u32 fib_id = 0;
15360   int ret;
15361
15362   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15363     {
15364       if (unformat (line_input, "ip4"))
15365         ip4 = 1;
15366       else if (unformat (line_input, "ip6"))
15367         ip6 = 1;
15368       else if (unformat (line_input, "default"))
15369         default_cop = 1;
15370       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15371                          vam, &sw_if_index))
15372         ;
15373       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15374         ;
15375       else if (unformat (line_input, "fib-id %d", &fib_id))
15376         ;
15377       else
15378         break;
15379     }
15380
15381   if (sw_if_index == ~0)
15382     {
15383       errmsg ("missing interface name or sw_if_index");
15384       return -99;
15385     }
15386
15387   /* Construct the API message */
15388   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15389   mp->sw_if_index = ntohl (sw_if_index);
15390   mp->fib_id = ntohl (fib_id);
15391   mp->ip4 = ip4;
15392   mp->ip6 = ip6;
15393   mp->default_cop = default_cop;
15394
15395   /* send it... */
15396   S (mp);
15397   /* Wait for the reply */
15398   W (ret);
15399   return ret;
15400 }
15401
15402 static int
15403 api_get_node_graph (vat_main_t * vam)
15404 {
15405   vl_api_get_node_graph_t *mp;
15406   int ret;
15407
15408   M (GET_NODE_GRAPH, mp);
15409
15410   /* send it... */
15411   S (mp);
15412   /* Wait for the reply */
15413   W (ret);
15414   return ret;
15415 }
15416
15417 /* *INDENT-OFF* */
15418 /** Used for parsing LISP eids */
15419 typedef CLIB_PACKED(struct{
15420   u8 addr[16];   /**< eid address */
15421   u32 len;       /**< prefix length if IP */
15422   u8 type;      /**< type of eid */
15423 }) lisp_eid_vat_t;
15424 /* *INDENT-ON* */
15425
15426 static uword
15427 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15428 {
15429   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15430
15431   memset (a, 0, sizeof (a[0]));
15432
15433   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15434     {
15435       a->type = 0;              /* ipv4 type */
15436     }
15437   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15438     {
15439       a->type = 1;              /* ipv6 type */
15440     }
15441   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15442     {
15443       a->type = 2;              /* mac type */
15444     }
15445   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15446     {
15447       a->type = 3;              /* NSH type */
15448       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15449       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15450     }
15451   else
15452     {
15453       return 0;
15454     }
15455
15456   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15457     {
15458       return 0;
15459     }
15460
15461   return 1;
15462 }
15463
15464 static int
15465 lisp_eid_size_vat (u8 type)
15466 {
15467   switch (type)
15468     {
15469     case 0:
15470       return 4;
15471     case 1:
15472       return 16;
15473     case 2:
15474       return 6;
15475     case 3:
15476       return 5;
15477     }
15478   return 0;
15479 }
15480
15481 static void
15482 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15483 {
15484   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15485 }
15486
15487 static int
15488 api_one_add_del_locator_set (vat_main_t * vam)
15489 {
15490   unformat_input_t *input = vam->input;
15491   vl_api_one_add_del_locator_set_t *mp;
15492   u8 is_add = 1;
15493   u8 *locator_set_name = NULL;
15494   u8 locator_set_name_set = 0;
15495   vl_api_local_locator_t locator, *locators = 0;
15496   u32 sw_if_index, priority, weight;
15497   u32 data_len = 0;
15498
15499   int ret;
15500   /* Parse args required to build the message */
15501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15502     {
15503       if (unformat (input, "del"))
15504         {
15505           is_add = 0;
15506         }
15507       else if (unformat (input, "locator-set %s", &locator_set_name))
15508         {
15509           locator_set_name_set = 1;
15510         }
15511       else if (unformat (input, "sw_if_index %u p %u w %u",
15512                          &sw_if_index, &priority, &weight))
15513         {
15514           locator.sw_if_index = htonl (sw_if_index);
15515           locator.priority = priority;
15516           locator.weight = weight;
15517           vec_add1 (locators, locator);
15518         }
15519       else
15520         if (unformat
15521             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15522              &sw_if_index, &priority, &weight))
15523         {
15524           locator.sw_if_index = htonl (sw_if_index);
15525           locator.priority = priority;
15526           locator.weight = weight;
15527           vec_add1 (locators, locator);
15528         }
15529       else
15530         break;
15531     }
15532
15533   if (locator_set_name_set == 0)
15534     {
15535       errmsg ("missing locator-set name");
15536       vec_free (locators);
15537       return -99;
15538     }
15539
15540   if (vec_len (locator_set_name) > 64)
15541     {
15542       errmsg ("locator-set name too long");
15543       vec_free (locator_set_name);
15544       vec_free (locators);
15545       return -99;
15546     }
15547   vec_add1 (locator_set_name, 0);
15548
15549   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15550
15551   /* Construct the API message */
15552   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15553
15554   mp->is_add = is_add;
15555   clib_memcpy (mp->locator_set_name, locator_set_name,
15556                vec_len (locator_set_name));
15557   vec_free (locator_set_name);
15558
15559   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15560   if (locators)
15561     clib_memcpy (mp->locators, locators, data_len);
15562   vec_free (locators);
15563
15564   /* send it... */
15565   S (mp);
15566
15567   /* Wait for a reply... */
15568   W (ret);
15569   return ret;
15570 }
15571
15572 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15573
15574 static int
15575 api_one_add_del_locator (vat_main_t * vam)
15576 {
15577   unformat_input_t *input = vam->input;
15578   vl_api_one_add_del_locator_t *mp;
15579   u32 tmp_if_index = ~0;
15580   u32 sw_if_index = ~0;
15581   u8 sw_if_index_set = 0;
15582   u8 sw_if_index_if_name_set = 0;
15583   u32 priority = ~0;
15584   u8 priority_set = 0;
15585   u32 weight = ~0;
15586   u8 weight_set = 0;
15587   u8 is_add = 1;
15588   u8 *locator_set_name = NULL;
15589   u8 locator_set_name_set = 0;
15590   int ret;
15591
15592   /* Parse args required to build the message */
15593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15594     {
15595       if (unformat (input, "del"))
15596         {
15597           is_add = 0;
15598         }
15599       else if (unformat (input, "locator-set %s", &locator_set_name))
15600         {
15601           locator_set_name_set = 1;
15602         }
15603       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15604                          &tmp_if_index))
15605         {
15606           sw_if_index_if_name_set = 1;
15607           sw_if_index = tmp_if_index;
15608         }
15609       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15610         {
15611           sw_if_index_set = 1;
15612           sw_if_index = tmp_if_index;
15613         }
15614       else if (unformat (input, "p %d", &priority))
15615         {
15616           priority_set = 1;
15617         }
15618       else if (unformat (input, "w %d", &weight))
15619         {
15620           weight_set = 1;
15621         }
15622       else
15623         break;
15624     }
15625
15626   if (locator_set_name_set == 0)
15627     {
15628       errmsg ("missing locator-set name");
15629       return -99;
15630     }
15631
15632   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15633     {
15634       errmsg ("missing sw_if_index");
15635       vec_free (locator_set_name);
15636       return -99;
15637     }
15638
15639   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15640     {
15641       errmsg ("cannot use both params interface name and sw_if_index");
15642       vec_free (locator_set_name);
15643       return -99;
15644     }
15645
15646   if (priority_set == 0)
15647     {
15648       errmsg ("missing locator-set priority");
15649       vec_free (locator_set_name);
15650       return -99;
15651     }
15652
15653   if (weight_set == 0)
15654     {
15655       errmsg ("missing locator-set weight");
15656       vec_free (locator_set_name);
15657       return -99;
15658     }
15659
15660   if (vec_len (locator_set_name) > 64)
15661     {
15662       errmsg ("locator-set name too long");
15663       vec_free (locator_set_name);
15664       return -99;
15665     }
15666   vec_add1 (locator_set_name, 0);
15667
15668   /* Construct the API message */
15669   M (ONE_ADD_DEL_LOCATOR, mp);
15670
15671   mp->is_add = is_add;
15672   mp->sw_if_index = ntohl (sw_if_index);
15673   mp->priority = priority;
15674   mp->weight = weight;
15675   clib_memcpy (mp->locator_set_name, locator_set_name,
15676                vec_len (locator_set_name));
15677   vec_free (locator_set_name);
15678
15679   /* send it... */
15680   S (mp);
15681
15682   /* Wait for a reply... */
15683   W (ret);
15684   return ret;
15685 }
15686
15687 #define api_lisp_add_del_locator api_one_add_del_locator
15688
15689 uword
15690 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15691 {
15692   u32 *key_id = va_arg (*args, u32 *);
15693   u8 *s = 0;
15694
15695   if (unformat (input, "%s", &s))
15696     {
15697       if (!strcmp ((char *) s, "sha1"))
15698         key_id[0] = HMAC_SHA_1_96;
15699       else if (!strcmp ((char *) s, "sha256"))
15700         key_id[0] = HMAC_SHA_256_128;
15701       else
15702         {
15703           clib_warning ("invalid key_id: '%s'", s);
15704           key_id[0] = HMAC_NO_KEY;
15705         }
15706     }
15707   else
15708     return 0;
15709
15710   vec_free (s);
15711   return 1;
15712 }
15713
15714 static int
15715 api_one_add_del_local_eid (vat_main_t * vam)
15716 {
15717   unformat_input_t *input = vam->input;
15718   vl_api_one_add_del_local_eid_t *mp;
15719   u8 is_add = 1;
15720   u8 eid_set = 0;
15721   lisp_eid_vat_t _eid, *eid = &_eid;
15722   u8 *locator_set_name = 0;
15723   u8 locator_set_name_set = 0;
15724   u32 vni = 0;
15725   u16 key_id = 0;
15726   u8 *key = 0;
15727   int ret;
15728
15729   /* Parse args required to build the message */
15730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (input, "del"))
15733         {
15734           is_add = 0;
15735         }
15736       else if (unformat (input, "vni %d", &vni))
15737         {
15738           ;
15739         }
15740       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15741         {
15742           eid_set = 1;
15743         }
15744       else if (unformat (input, "locator-set %s", &locator_set_name))
15745         {
15746           locator_set_name_set = 1;
15747         }
15748       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15749         ;
15750       else if (unformat (input, "secret-key %_%v%_", &key))
15751         ;
15752       else
15753         break;
15754     }
15755
15756   if (locator_set_name_set == 0)
15757     {
15758       errmsg ("missing locator-set name");
15759       return -99;
15760     }
15761
15762   if (0 == eid_set)
15763     {
15764       errmsg ("EID address not set!");
15765       vec_free (locator_set_name);
15766       return -99;
15767     }
15768
15769   if (key && (0 == key_id))
15770     {
15771       errmsg ("invalid key_id!");
15772       return -99;
15773     }
15774
15775   if (vec_len (key) > 64)
15776     {
15777       errmsg ("key too long");
15778       vec_free (key);
15779       return -99;
15780     }
15781
15782   if (vec_len (locator_set_name) > 64)
15783     {
15784       errmsg ("locator-set name too long");
15785       vec_free (locator_set_name);
15786       return -99;
15787     }
15788   vec_add1 (locator_set_name, 0);
15789
15790   /* Construct the API message */
15791   M (ONE_ADD_DEL_LOCAL_EID, mp);
15792
15793   mp->is_add = is_add;
15794   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15795   mp->eid_type = eid->type;
15796   mp->prefix_len = eid->len;
15797   mp->vni = clib_host_to_net_u32 (vni);
15798   mp->key_id = clib_host_to_net_u16 (key_id);
15799   clib_memcpy (mp->locator_set_name, locator_set_name,
15800                vec_len (locator_set_name));
15801   clib_memcpy (mp->key, key, vec_len (key));
15802
15803   vec_free (locator_set_name);
15804   vec_free (key);
15805
15806   /* send it... */
15807   S (mp);
15808
15809   /* Wait for a reply... */
15810   W (ret);
15811   return ret;
15812 }
15813
15814 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15815
15816 static int
15817 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15818 {
15819   u32 dp_table = 0, vni = 0;;
15820   unformat_input_t *input = vam->input;
15821   vl_api_gpe_add_del_fwd_entry_t *mp;
15822   u8 is_add = 1;
15823   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15824   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15825   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15826   u32 action = ~0, w;
15827   ip4_address_t rmt_rloc4, lcl_rloc4;
15828   ip6_address_t rmt_rloc6, lcl_rloc6;
15829   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15830   int ret;
15831
15832   memset (&rloc, 0, sizeof (rloc));
15833
15834   /* Parse args required to build the message */
15835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15836     {
15837       if (unformat (input, "del"))
15838         is_add = 0;
15839       else if (unformat (input, "add"))
15840         is_add = 1;
15841       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15842         {
15843           rmt_eid_set = 1;
15844         }
15845       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15846         {
15847           lcl_eid_set = 1;
15848         }
15849       else if (unformat (input, "vrf %d", &dp_table))
15850         ;
15851       else if (unformat (input, "bd %d", &dp_table))
15852         ;
15853       else if (unformat (input, "vni %d", &vni))
15854         ;
15855       else if (unformat (input, "w %d", &w))
15856         {
15857           if (!curr_rloc)
15858             {
15859               errmsg ("No RLOC configured for setting priority/weight!");
15860               return -99;
15861             }
15862           curr_rloc->weight = w;
15863         }
15864       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15865                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15866         {
15867           rloc.is_ip4 = 1;
15868
15869           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15870           rloc.weight = 0;
15871           vec_add1 (lcl_locs, rloc);
15872
15873           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15874           vec_add1 (rmt_locs, rloc);
15875           /* weight saved in rmt loc */
15876           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15877         }
15878       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15879                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15880         {
15881           rloc.is_ip4 = 0;
15882           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15883           rloc.weight = 0;
15884           vec_add1 (lcl_locs, rloc);
15885
15886           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15887           vec_add1 (rmt_locs, rloc);
15888           /* weight saved in rmt loc */
15889           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15890         }
15891       else if (unformat (input, "action %d", &action))
15892         {
15893           ;
15894         }
15895       else
15896         {
15897           clib_warning ("parse error '%U'", format_unformat_error, input);
15898           return -99;
15899         }
15900     }
15901
15902   if (!rmt_eid_set)
15903     {
15904       errmsg ("remote eid addresses not set");
15905       return -99;
15906     }
15907
15908   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15909     {
15910       errmsg ("eid types don't match");
15911       return -99;
15912     }
15913
15914   if (0 == rmt_locs && (u32) ~ 0 == action)
15915     {
15916       errmsg ("action not set for negative mapping");
15917       return -99;
15918     }
15919
15920   /* Construct the API message */
15921   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15922       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15923
15924   mp->is_add = is_add;
15925   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15926   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15927   mp->eid_type = rmt_eid->type;
15928   mp->dp_table = clib_host_to_net_u32 (dp_table);
15929   mp->vni = clib_host_to_net_u32 (vni);
15930   mp->rmt_len = rmt_eid->len;
15931   mp->lcl_len = lcl_eid->len;
15932   mp->action = action;
15933
15934   if (0 != rmt_locs && 0 != lcl_locs)
15935     {
15936       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15937       clib_memcpy (mp->locs, lcl_locs,
15938                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15939
15940       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15941       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15942                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15943     }
15944   vec_free (lcl_locs);
15945   vec_free (rmt_locs);
15946
15947   /* send it... */
15948   S (mp);
15949
15950   /* Wait for a reply... */
15951   W (ret);
15952   return ret;
15953 }
15954
15955 static int
15956 api_one_add_del_map_server (vat_main_t * vam)
15957 {
15958   unformat_input_t *input = vam->input;
15959   vl_api_one_add_del_map_server_t *mp;
15960   u8 is_add = 1;
15961   u8 ipv4_set = 0;
15962   u8 ipv6_set = 0;
15963   ip4_address_t ipv4;
15964   ip6_address_t ipv6;
15965   int ret;
15966
15967   /* Parse args required to build the message */
15968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15969     {
15970       if (unformat (input, "del"))
15971         {
15972           is_add = 0;
15973         }
15974       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15975         {
15976           ipv4_set = 1;
15977         }
15978       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15979         {
15980           ipv6_set = 1;
15981         }
15982       else
15983         break;
15984     }
15985
15986   if (ipv4_set && ipv6_set)
15987     {
15988       errmsg ("both eid v4 and v6 addresses set");
15989       return -99;
15990     }
15991
15992   if (!ipv4_set && !ipv6_set)
15993     {
15994       errmsg ("eid addresses not set");
15995       return -99;
15996     }
15997
15998   /* Construct the API message */
15999   M (ONE_ADD_DEL_MAP_SERVER, mp);
16000
16001   mp->is_add = is_add;
16002   if (ipv6_set)
16003     {
16004       mp->is_ipv6 = 1;
16005       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16006     }
16007   else
16008     {
16009       mp->is_ipv6 = 0;
16010       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16011     }
16012
16013   /* send it... */
16014   S (mp);
16015
16016   /* Wait for a reply... */
16017   W (ret);
16018   return ret;
16019 }
16020
16021 #define api_lisp_add_del_map_server api_one_add_del_map_server
16022
16023 static int
16024 api_one_add_del_map_resolver (vat_main_t * vam)
16025 {
16026   unformat_input_t *input = vam->input;
16027   vl_api_one_add_del_map_resolver_t *mp;
16028   u8 is_add = 1;
16029   u8 ipv4_set = 0;
16030   u8 ipv6_set = 0;
16031   ip4_address_t ipv4;
16032   ip6_address_t ipv6;
16033   int ret;
16034
16035   /* Parse args required to build the message */
16036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16037     {
16038       if (unformat (input, "del"))
16039         {
16040           is_add = 0;
16041         }
16042       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16043         {
16044           ipv4_set = 1;
16045         }
16046       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16047         {
16048           ipv6_set = 1;
16049         }
16050       else
16051         break;
16052     }
16053
16054   if (ipv4_set && ipv6_set)
16055     {
16056       errmsg ("both eid v4 and v6 addresses set");
16057       return -99;
16058     }
16059
16060   if (!ipv4_set && !ipv6_set)
16061     {
16062       errmsg ("eid addresses not set");
16063       return -99;
16064     }
16065
16066   /* Construct the API message */
16067   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16068
16069   mp->is_add = is_add;
16070   if (ipv6_set)
16071     {
16072       mp->is_ipv6 = 1;
16073       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16074     }
16075   else
16076     {
16077       mp->is_ipv6 = 0;
16078       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16079     }
16080
16081   /* send it... */
16082   S (mp);
16083
16084   /* Wait for a reply... */
16085   W (ret);
16086   return ret;
16087 }
16088
16089 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16090
16091 static int
16092 api_lisp_gpe_enable_disable (vat_main_t * vam)
16093 {
16094   unformat_input_t *input = vam->input;
16095   vl_api_gpe_enable_disable_t *mp;
16096   u8 is_set = 0;
16097   u8 is_en = 1;
16098   int ret;
16099
16100   /* Parse args required to build the message */
16101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16102     {
16103       if (unformat (input, "enable"))
16104         {
16105           is_set = 1;
16106           is_en = 1;
16107         }
16108       else if (unformat (input, "disable"))
16109         {
16110           is_set = 1;
16111           is_en = 0;
16112         }
16113       else
16114         break;
16115     }
16116
16117   if (is_set == 0)
16118     {
16119       errmsg ("Value not set");
16120       return -99;
16121     }
16122
16123   /* Construct the API message */
16124   M (GPE_ENABLE_DISABLE, mp);
16125
16126   mp->is_en = is_en;
16127
16128   /* send it... */
16129   S (mp);
16130
16131   /* Wait for a reply... */
16132   W (ret);
16133   return ret;
16134 }
16135
16136 static int
16137 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16138 {
16139   unformat_input_t *input = vam->input;
16140   vl_api_one_rloc_probe_enable_disable_t *mp;
16141   u8 is_set = 0;
16142   u8 is_en = 0;
16143   int ret;
16144
16145   /* Parse args required to build the message */
16146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (input, "enable"))
16149         {
16150           is_set = 1;
16151           is_en = 1;
16152         }
16153       else if (unformat (input, "disable"))
16154         is_set = 1;
16155       else
16156         break;
16157     }
16158
16159   if (!is_set)
16160     {
16161       errmsg ("Value not set");
16162       return -99;
16163     }
16164
16165   /* Construct the API message */
16166   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16167
16168   mp->is_enabled = is_en;
16169
16170   /* send it... */
16171   S (mp);
16172
16173   /* Wait for a reply... */
16174   W (ret);
16175   return ret;
16176 }
16177
16178 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16179
16180 static int
16181 api_one_map_register_enable_disable (vat_main_t * vam)
16182 {
16183   unformat_input_t *input = vam->input;
16184   vl_api_one_map_register_enable_disable_t *mp;
16185   u8 is_set = 0;
16186   u8 is_en = 0;
16187   int ret;
16188
16189   /* Parse args required to build the message */
16190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16191     {
16192       if (unformat (input, "enable"))
16193         {
16194           is_set = 1;
16195           is_en = 1;
16196         }
16197       else if (unformat (input, "disable"))
16198         is_set = 1;
16199       else
16200         break;
16201     }
16202
16203   if (!is_set)
16204     {
16205       errmsg ("Value not set");
16206       return -99;
16207     }
16208
16209   /* Construct the API message */
16210   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16211
16212   mp->is_enabled = is_en;
16213
16214   /* send it... */
16215   S (mp);
16216
16217   /* Wait for a reply... */
16218   W (ret);
16219   return ret;
16220 }
16221
16222 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16223
16224 static int
16225 api_one_enable_disable (vat_main_t * vam)
16226 {
16227   unformat_input_t *input = vam->input;
16228   vl_api_one_enable_disable_t *mp;
16229   u8 is_set = 0;
16230   u8 is_en = 0;
16231   int ret;
16232
16233   /* Parse args required to build the message */
16234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16235     {
16236       if (unformat (input, "enable"))
16237         {
16238           is_set = 1;
16239           is_en = 1;
16240         }
16241       else if (unformat (input, "disable"))
16242         {
16243           is_set = 1;
16244         }
16245       else
16246         break;
16247     }
16248
16249   if (!is_set)
16250     {
16251       errmsg ("Value not set");
16252       return -99;
16253     }
16254
16255   /* Construct the API message */
16256   M (ONE_ENABLE_DISABLE, mp);
16257
16258   mp->is_en = is_en;
16259
16260   /* send it... */
16261   S (mp);
16262
16263   /* Wait for a reply... */
16264   W (ret);
16265   return ret;
16266 }
16267
16268 #define api_lisp_enable_disable api_one_enable_disable
16269
16270 static int
16271 api_show_one_map_register_state (vat_main_t * vam)
16272 {
16273   vl_api_show_one_map_register_state_t *mp;
16274   int ret;
16275
16276   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16277
16278   /* send */
16279   S (mp);
16280
16281   /* wait for reply */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 #define api_show_lisp_map_register_state api_show_one_map_register_state
16287
16288 static int
16289 api_show_one_rloc_probe_state (vat_main_t * vam)
16290 {
16291   vl_api_show_one_rloc_probe_state_t *mp;
16292   int ret;
16293
16294   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16295
16296   /* send */
16297   S (mp);
16298
16299   /* wait for reply */
16300   W (ret);
16301   return ret;
16302 }
16303
16304 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16305
16306 static int
16307 api_one_add_del_ndp_entry (vat_main_t * vam)
16308 {
16309   vl_api_one_add_del_ndp_entry_t *mp;
16310   unformat_input_t *input = vam->input;
16311   u8 is_add = 1;
16312   u8 mac_set = 0;
16313   u8 bd_set = 0;
16314   u8 ip_set = 0;
16315   u8 mac[6] = { 0, };
16316   u8 ip6[16] = { 0, };
16317   u32 bd = ~0;
16318   int ret;
16319
16320   /* Parse args required to build the message */
16321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16322     {
16323       if (unformat (input, "del"))
16324         is_add = 0;
16325       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16326         mac_set = 1;
16327       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16328         ip_set = 1;
16329       else if (unformat (input, "bd %d", &bd))
16330         bd_set = 1;
16331       else
16332         {
16333           errmsg ("parse error '%U'", format_unformat_error, input);
16334           return -99;
16335         }
16336     }
16337
16338   if (!bd_set || !ip_set || (!mac_set && is_add))
16339     {
16340       errmsg ("Missing BD, IP or MAC!");
16341       return -99;
16342     }
16343
16344   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16345   mp->is_add = is_add;
16346   clib_memcpy (mp->mac, mac, 6);
16347   mp->bd = clib_host_to_net_u32 (bd);
16348   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16349
16350   /* send */
16351   S (mp);
16352
16353   /* wait for reply */
16354   W (ret);
16355   return ret;
16356 }
16357
16358 static int
16359 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16360 {
16361   vl_api_one_add_del_l2_arp_entry_t *mp;
16362   unformat_input_t *input = vam->input;
16363   u8 is_add = 1;
16364   u8 mac_set = 0;
16365   u8 bd_set = 0;
16366   u8 ip_set = 0;
16367   u8 mac[6] = { 0, };
16368   u32 ip4 = 0, bd = ~0;
16369   int ret;
16370
16371   /* Parse args required to build the message */
16372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (input, "del"))
16375         is_add = 0;
16376       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16377         mac_set = 1;
16378       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16379         ip_set = 1;
16380       else if (unformat (input, "bd %d", &bd))
16381         bd_set = 1;
16382       else
16383         {
16384           errmsg ("parse error '%U'", format_unformat_error, input);
16385           return -99;
16386         }
16387     }
16388
16389   if (!bd_set || !ip_set || (!mac_set && is_add))
16390     {
16391       errmsg ("Missing BD, IP or MAC!");
16392       return -99;
16393     }
16394
16395   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16396   mp->is_add = is_add;
16397   clib_memcpy (mp->mac, mac, 6);
16398   mp->bd = clib_host_to_net_u32 (bd);
16399   mp->ip4 = ip4;
16400
16401   /* send */
16402   S (mp);
16403
16404   /* wait for reply */
16405   W (ret);
16406   return ret;
16407 }
16408
16409 static int
16410 api_one_ndp_bd_get (vat_main_t * vam)
16411 {
16412   vl_api_one_ndp_bd_get_t *mp;
16413   int ret;
16414
16415   M (ONE_NDP_BD_GET, mp);
16416
16417   /* send */
16418   S (mp);
16419
16420   /* wait for reply */
16421   W (ret);
16422   return ret;
16423 }
16424
16425 static int
16426 api_one_ndp_entries_get (vat_main_t * vam)
16427 {
16428   vl_api_one_ndp_entries_get_t *mp;
16429   unformat_input_t *input = vam->input;
16430   u8 bd_set = 0;
16431   u32 bd = ~0;
16432   int ret;
16433
16434   /* Parse args required to build the message */
16435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16436     {
16437       if (unformat (input, "bd %d", &bd))
16438         bd_set = 1;
16439       else
16440         {
16441           errmsg ("parse error '%U'", format_unformat_error, input);
16442           return -99;
16443         }
16444     }
16445
16446   if (!bd_set)
16447     {
16448       errmsg ("Expected bridge domain!");
16449       return -99;
16450     }
16451
16452   M (ONE_NDP_ENTRIES_GET, mp);
16453   mp->bd = clib_host_to_net_u32 (bd);
16454
16455   /* send */
16456   S (mp);
16457
16458   /* wait for reply */
16459   W (ret);
16460   return ret;
16461 }
16462
16463 static int
16464 api_one_l2_arp_bd_get (vat_main_t * vam)
16465 {
16466   vl_api_one_l2_arp_bd_get_t *mp;
16467   int ret;
16468
16469   M (ONE_L2_ARP_BD_GET, mp);
16470
16471   /* send */
16472   S (mp);
16473
16474   /* wait for reply */
16475   W (ret);
16476   return ret;
16477 }
16478
16479 static int
16480 api_one_l2_arp_entries_get (vat_main_t * vam)
16481 {
16482   vl_api_one_l2_arp_entries_get_t *mp;
16483   unformat_input_t *input = vam->input;
16484   u8 bd_set = 0;
16485   u32 bd = ~0;
16486   int ret;
16487
16488   /* Parse args required to build the message */
16489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16490     {
16491       if (unformat (input, "bd %d", &bd))
16492         bd_set = 1;
16493       else
16494         {
16495           errmsg ("parse error '%U'", format_unformat_error, input);
16496           return -99;
16497         }
16498     }
16499
16500   if (!bd_set)
16501     {
16502       errmsg ("Expected bridge domain!");
16503       return -99;
16504     }
16505
16506   M (ONE_L2_ARP_ENTRIES_GET, mp);
16507   mp->bd = clib_host_to_net_u32 (bd);
16508
16509   /* send */
16510   S (mp);
16511
16512   /* wait for reply */
16513   W (ret);
16514   return ret;
16515 }
16516
16517 static int
16518 api_one_stats_enable_disable (vat_main_t * vam)
16519 {
16520   vl_api_one_stats_enable_disable_t *mp;
16521   unformat_input_t *input = vam->input;
16522   u8 is_set = 0;
16523   u8 is_en = 0;
16524   int ret;
16525
16526   /* Parse args required to build the message */
16527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16528     {
16529       if (unformat (input, "enable"))
16530         {
16531           is_set = 1;
16532           is_en = 1;
16533         }
16534       else if (unformat (input, "disable"))
16535         {
16536           is_set = 1;
16537         }
16538       else
16539         break;
16540     }
16541
16542   if (!is_set)
16543     {
16544       errmsg ("Value not set");
16545       return -99;
16546     }
16547
16548   M (ONE_STATS_ENABLE_DISABLE, mp);
16549   mp->is_en = is_en;
16550
16551   /* send */
16552   S (mp);
16553
16554   /* wait for reply */
16555   W (ret);
16556   return ret;
16557 }
16558
16559 static int
16560 api_show_one_stats_enable_disable (vat_main_t * vam)
16561 {
16562   vl_api_show_one_stats_enable_disable_t *mp;
16563   int ret;
16564
16565   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16566
16567   /* send */
16568   S (mp);
16569
16570   /* wait for reply */
16571   W (ret);
16572   return ret;
16573 }
16574
16575 static int
16576 api_show_one_map_request_mode (vat_main_t * vam)
16577 {
16578   vl_api_show_one_map_request_mode_t *mp;
16579   int ret;
16580
16581   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16582
16583   /* send */
16584   S (mp);
16585
16586   /* wait for reply */
16587   W (ret);
16588   return ret;
16589 }
16590
16591 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16592
16593 static int
16594 api_one_map_request_mode (vat_main_t * vam)
16595 {
16596   unformat_input_t *input = vam->input;
16597   vl_api_one_map_request_mode_t *mp;
16598   u8 mode = 0;
16599   int ret;
16600
16601   /* Parse args required to build the message */
16602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16603     {
16604       if (unformat (input, "dst-only"))
16605         mode = 0;
16606       else if (unformat (input, "src-dst"))
16607         mode = 1;
16608       else
16609         {
16610           errmsg ("parse error '%U'", format_unformat_error, input);
16611           return -99;
16612         }
16613     }
16614
16615   M (ONE_MAP_REQUEST_MODE, mp);
16616
16617   mp->mode = mode;
16618
16619   /* send */
16620   S (mp);
16621
16622   /* wait for reply */
16623   W (ret);
16624   return ret;
16625 }
16626
16627 #define api_lisp_map_request_mode api_one_map_request_mode
16628
16629 /**
16630  * Enable/disable ONE proxy ITR.
16631  *
16632  * @param vam vpp API test context
16633  * @return return code
16634  */
16635 static int
16636 api_one_pitr_set_locator_set (vat_main_t * vam)
16637 {
16638   u8 ls_name_set = 0;
16639   unformat_input_t *input = vam->input;
16640   vl_api_one_pitr_set_locator_set_t *mp;
16641   u8 is_add = 1;
16642   u8 *ls_name = 0;
16643   int ret;
16644
16645   /* Parse args required to build the message */
16646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16647     {
16648       if (unformat (input, "del"))
16649         is_add = 0;
16650       else if (unformat (input, "locator-set %s", &ls_name))
16651         ls_name_set = 1;
16652       else
16653         {
16654           errmsg ("parse error '%U'", format_unformat_error, input);
16655           return -99;
16656         }
16657     }
16658
16659   if (!ls_name_set)
16660     {
16661       errmsg ("locator-set name not set!");
16662       return -99;
16663     }
16664
16665   M (ONE_PITR_SET_LOCATOR_SET, mp);
16666
16667   mp->is_add = is_add;
16668   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16669   vec_free (ls_name);
16670
16671   /* send */
16672   S (mp);
16673
16674   /* wait for reply */
16675   W (ret);
16676   return ret;
16677 }
16678
16679 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16680
16681 static int
16682 api_one_nsh_set_locator_set (vat_main_t * vam)
16683 {
16684   u8 ls_name_set = 0;
16685   unformat_input_t *input = vam->input;
16686   vl_api_one_nsh_set_locator_set_t *mp;
16687   u8 is_add = 1;
16688   u8 *ls_name = 0;
16689   int ret;
16690
16691   /* Parse args required to build the message */
16692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16693     {
16694       if (unformat (input, "del"))
16695         is_add = 0;
16696       else if (unformat (input, "ls %s", &ls_name))
16697         ls_name_set = 1;
16698       else
16699         {
16700           errmsg ("parse error '%U'", format_unformat_error, input);
16701           return -99;
16702         }
16703     }
16704
16705   if (!ls_name_set && is_add)
16706     {
16707       errmsg ("locator-set name not set!");
16708       return -99;
16709     }
16710
16711   M (ONE_NSH_SET_LOCATOR_SET, mp);
16712
16713   mp->is_add = is_add;
16714   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16715   vec_free (ls_name);
16716
16717   /* send */
16718   S (mp);
16719
16720   /* wait for reply */
16721   W (ret);
16722   return ret;
16723 }
16724
16725 static int
16726 api_show_one_pitr (vat_main_t * vam)
16727 {
16728   vl_api_show_one_pitr_t *mp;
16729   int ret;
16730
16731   if (!vam->json_output)
16732     {
16733       print (vam->ofp, "%=20s", "lisp status:");
16734     }
16735
16736   M (SHOW_ONE_PITR, mp);
16737   /* send it... */
16738   S (mp);
16739
16740   /* Wait for a reply... */
16741   W (ret);
16742   return ret;
16743 }
16744
16745 #define api_show_lisp_pitr api_show_one_pitr
16746
16747 static int
16748 api_one_use_petr (vat_main_t * vam)
16749 {
16750   unformat_input_t *input = vam->input;
16751   vl_api_one_use_petr_t *mp;
16752   u8 is_add = 0;
16753   ip_address_t ip;
16754   int ret;
16755
16756   memset (&ip, 0, sizeof (ip));
16757
16758   /* Parse args required to build the message */
16759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16760     {
16761       if (unformat (input, "disable"))
16762         is_add = 0;
16763       else
16764         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16765         {
16766           is_add = 1;
16767           ip_addr_version (&ip) = IP4;
16768         }
16769       else
16770         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16771         {
16772           is_add = 1;
16773           ip_addr_version (&ip) = IP6;
16774         }
16775       else
16776         {
16777           errmsg ("parse error '%U'", format_unformat_error, input);
16778           return -99;
16779         }
16780     }
16781
16782   M (ONE_USE_PETR, mp);
16783
16784   mp->is_add = is_add;
16785   if (is_add)
16786     {
16787       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16788       if (mp->is_ip4)
16789         clib_memcpy (mp->address, &ip, 4);
16790       else
16791         clib_memcpy (mp->address, &ip, 16);
16792     }
16793
16794   /* send */
16795   S (mp);
16796
16797   /* wait for reply */
16798   W (ret);
16799   return ret;
16800 }
16801
16802 #define api_lisp_use_petr api_one_use_petr
16803
16804 static int
16805 api_show_one_nsh_mapping (vat_main_t * vam)
16806 {
16807   vl_api_show_one_use_petr_t *mp;
16808   int ret;
16809
16810   if (!vam->json_output)
16811     {
16812       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16813     }
16814
16815   M (SHOW_ONE_NSH_MAPPING, mp);
16816   /* send it... */
16817   S (mp);
16818
16819   /* Wait for a reply... */
16820   W (ret);
16821   return ret;
16822 }
16823
16824 static int
16825 api_show_one_use_petr (vat_main_t * vam)
16826 {
16827   vl_api_show_one_use_petr_t *mp;
16828   int ret;
16829
16830   if (!vam->json_output)
16831     {
16832       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16833     }
16834
16835   M (SHOW_ONE_USE_PETR, mp);
16836   /* send it... */
16837   S (mp);
16838
16839   /* Wait for a reply... */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 #define api_show_lisp_use_petr api_show_one_use_petr
16845
16846 /**
16847  * Add/delete mapping between vni and vrf
16848  */
16849 static int
16850 api_one_eid_table_add_del_map (vat_main_t * vam)
16851 {
16852   unformat_input_t *input = vam->input;
16853   vl_api_one_eid_table_add_del_map_t *mp;
16854   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16855   u32 vni, vrf, bd_index;
16856   int ret;
16857
16858   /* Parse args required to build the message */
16859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16860     {
16861       if (unformat (input, "del"))
16862         is_add = 0;
16863       else if (unformat (input, "vrf %d", &vrf))
16864         vrf_set = 1;
16865       else if (unformat (input, "bd_index %d", &bd_index))
16866         bd_index_set = 1;
16867       else if (unformat (input, "vni %d", &vni))
16868         vni_set = 1;
16869       else
16870         break;
16871     }
16872
16873   if (!vni_set || (!vrf_set && !bd_index_set))
16874     {
16875       errmsg ("missing arguments!");
16876       return -99;
16877     }
16878
16879   if (vrf_set && bd_index_set)
16880     {
16881       errmsg ("error: both vrf and bd entered!");
16882       return -99;
16883     }
16884
16885   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16886
16887   mp->is_add = is_add;
16888   mp->vni = htonl (vni);
16889   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16890   mp->is_l2 = bd_index_set;
16891
16892   /* send */
16893   S (mp);
16894
16895   /* wait for reply */
16896   W (ret);
16897   return ret;
16898 }
16899
16900 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16901
16902 uword
16903 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16904 {
16905   u32 *action = va_arg (*args, u32 *);
16906   u8 *s = 0;
16907
16908   if (unformat (input, "%s", &s))
16909     {
16910       if (!strcmp ((char *) s, "no-action"))
16911         action[0] = 0;
16912       else if (!strcmp ((char *) s, "natively-forward"))
16913         action[0] = 1;
16914       else if (!strcmp ((char *) s, "send-map-request"))
16915         action[0] = 2;
16916       else if (!strcmp ((char *) s, "drop"))
16917         action[0] = 3;
16918       else
16919         {
16920           clib_warning ("invalid action: '%s'", s);
16921           action[0] = 3;
16922         }
16923     }
16924   else
16925     return 0;
16926
16927   vec_free (s);
16928   return 1;
16929 }
16930
16931 /**
16932  * Add/del remote mapping to/from ONE control plane
16933  *
16934  * @param vam vpp API test context
16935  * @return return code
16936  */
16937 static int
16938 api_one_add_del_remote_mapping (vat_main_t * vam)
16939 {
16940   unformat_input_t *input = vam->input;
16941   vl_api_one_add_del_remote_mapping_t *mp;
16942   u32 vni = 0;
16943   lisp_eid_vat_t _eid, *eid = &_eid;
16944   lisp_eid_vat_t _seid, *seid = &_seid;
16945   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16946   u32 action = ~0, p, w, data_len;
16947   ip4_address_t rloc4;
16948   ip6_address_t rloc6;
16949   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16950   int ret;
16951
16952   memset (&rloc, 0, sizeof (rloc));
16953
16954   /* Parse args required to build the message */
16955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16956     {
16957       if (unformat (input, "del-all"))
16958         {
16959           del_all = 1;
16960         }
16961       else if (unformat (input, "del"))
16962         {
16963           is_add = 0;
16964         }
16965       else if (unformat (input, "add"))
16966         {
16967           is_add = 1;
16968         }
16969       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16970         {
16971           eid_set = 1;
16972         }
16973       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16974         {
16975           seid_set = 1;
16976         }
16977       else if (unformat (input, "vni %d", &vni))
16978         {
16979           ;
16980         }
16981       else if (unformat (input, "p %d w %d", &p, &w))
16982         {
16983           if (!curr_rloc)
16984             {
16985               errmsg ("No RLOC configured for setting priority/weight!");
16986               return -99;
16987             }
16988           curr_rloc->priority = p;
16989           curr_rloc->weight = w;
16990         }
16991       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16992         {
16993           rloc.is_ip4 = 1;
16994           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16995           vec_add1 (rlocs, rloc);
16996           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16997         }
16998       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16999         {
17000           rloc.is_ip4 = 0;
17001           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17002           vec_add1 (rlocs, rloc);
17003           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17004         }
17005       else if (unformat (input, "action %U",
17006                          unformat_negative_mapping_action, &action))
17007         {
17008           ;
17009         }
17010       else
17011         {
17012           clib_warning ("parse error '%U'", format_unformat_error, input);
17013           return -99;
17014         }
17015     }
17016
17017   if (0 == eid_set)
17018     {
17019       errmsg ("missing params!");
17020       return -99;
17021     }
17022
17023   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17024     {
17025       errmsg ("no action set for negative map-reply!");
17026       return -99;
17027     }
17028
17029   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17030
17031   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17032   mp->is_add = is_add;
17033   mp->vni = htonl (vni);
17034   mp->action = (u8) action;
17035   mp->is_src_dst = seid_set;
17036   mp->eid_len = eid->len;
17037   mp->seid_len = seid->len;
17038   mp->del_all = del_all;
17039   mp->eid_type = eid->type;
17040   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17041   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17042
17043   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17044   clib_memcpy (mp->rlocs, rlocs, data_len);
17045   vec_free (rlocs);
17046
17047   /* send it... */
17048   S (mp);
17049
17050   /* Wait for a reply... */
17051   W (ret);
17052   return ret;
17053 }
17054
17055 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17056
17057 /**
17058  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17059  * forwarding entries in data-plane accordingly.
17060  *
17061  * @param vam vpp API test context
17062  * @return return code
17063  */
17064 static int
17065 api_one_add_del_adjacency (vat_main_t * vam)
17066 {
17067   unformat_input_t *input = vam->input;
17068   vl_api_one_add_del_adjacency_t *mp;
17069   u32 vni = 0;
17070   ip4_address_t leid4, reid4;
17071   ip6_address_t leid6, reid6;
17072   u8 reid_mac[6] = { 0 };
17073   u8 leid_mac[6] = { 0 };
17074   u8 reid_type, leid_type;
17075   u32 leid_len = 0, reid_len = 0, len;
17076   u8 is_add = 1;
17077   int ret;
17078
17079   leid_type = reid_type = (u8) ~ 0;
17080
17081   /* Parse args required to build the message */
17082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17083     {
17084       if (unformat (input, "del"))
17085         {
17086           is_add = 0;
17087         }
17088       else if (unformat (input, "add"))
17089         {
17090           is_add = 1;
17091         }
17092       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17093                          &reid4, &len))
17094         {
17095           reid_type = 0;        /* ipv4 */
17096           reid_len = len;
17097         }
17098       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17099                          &reid6, &len))
17100         {
17101           reid_type = 1;        /* ipv6 */
17102           reid_len = len;
17103         }
17104       else if (unformat (input, "reid %U", unformat_ethernet_address,
17105                          reid_mac))
17106         {
17107           reid_type = 2;        /* mac */
17108         }
17109       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17110                          &leid4, &len))
17111         {
17112           leid_type = 0;        /* ipv4 */
17113           leid_len = len;
17114         }
17115       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17116                          &leid6, &len))
17117         {
17118           leid_type = 1;        /* ipv6 */
17119           leid_len = len;
17120         }
17121       else if (unformat (input, "leid %U", unformat_ethernet_address,
17122                          leid_mac))
17123         {
17124           leid_type = 2;        /* mac */
17125         }
17126       else if (unformat (input, "vni %d", &vni))
17127         {
17128           ;
17129         }
17130       else
17131         {
17132           errmsg ("parse error '%U'", format_unformat_error, input);
17133           return -99;
17134         }
17135     }
17136
17137   if ((u8) ~ 0 == reid_type)
17138     {
17139       errmsg ("missing params!");
17140       return -99;
17141     }
17142
17143   if (leid_type != reid_type)
17144     {
17145       errmsg ("remote and local EIDs are of different types!");
17146       return -99;
17147     }
17148
17149   M (ONE_ADD_DEL_ADJACENCY, mp);
17150   mp->is_add = is_add;
17151   mp->vni = htonl (vni);
17152   mp->leid_len = leid_len;
17153   mp->reid_len = reid_len;
17154   mp->eid_type = reid_type;
17155
17156   switch (mp->eid_type)
17157     {
17158     case 0:
17159       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17160       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17161       break;
17162     case 1:
17163       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17164       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17165       break;
17166     case 2:
17167       clib_memcpy (mp->leid, leid_mac, 6);
17168       clib_memcpy (mp->reid, reid_mac, 6);
17169       break;
17170     default:
17171       errmsg ("unknown EID type %d!", mp->eid_type);
17172       return 0;
17173     }
17174
17175   /* send it... */
17176   S (mp);
17177
17178   /* Wait for a reply... */
17179   W (ret);
17180   return ret;
17181 }
17182
17183 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17184
17185 uword
17186 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17187 {
17188   u32 *mode = va_arg (*args, u32 *);
17189
17190   if (unformat (input, "lisp"))
17191     *mode = 0;
17192   else if (unformat (input, "vxlan"))
17193     *mode = 1;
17194   else
17195     return 0;
17196
17197   return 1;
17198 }
17199
17200 static int
17201 api_gpe_get_encap_mode (vat_main_t * vam)
17202 {
17203   vl_api_gpe_get_encap_mode_t *mp;
17204   int ret;
17205
17206   /* Construct the API message */
17207   M (GPE_GET_ENCAP_MODE, mp);
17208
17209   /* send it... */
17210   S (mp);
17211
17212   /* Wait for a reply... */
17213   W (ret);
17214   return ret;
17215 }
17216
17217 static int
17218 api_gpe_set_encap_mode (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_gpe_set_encap_mode_t *mp;
17222   int ret;
17223   u32 mode = 0;
17224
17225   /* Parse args required to build the message */
17226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17229         ;
17230       else
17231         break;
17232     }
17233
17234   /* Construct the API message */
17235   M (GPE_SET_ENCAP_MODE, mp);
17236
17237   mp->mode = mode;
17238
17239   /* send it... */
17240   S (mp);
17241
17242   /* Wait for a reply... */
17243   W (ret);
17244   return ret;
17245 }
17246
17247 static int
17248 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17249 {
17250   unformat_input_t *input = vam->input;
17251   vl_api_gpe_add_del_iface_t *mp;
17252   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17253   u32 dp_table = 0, vni = 0;
17254   int ret;
17255
17256   /* Parse args required to build the message */
17257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (input, "up"))
17260         {
17261           action_set = 1;
17262           is_add = 1;
17263         }
17264       else if (unformat (input, "down"))
17265         {
17266           action_set = 1;
17267           is_add = 0;
17268         }
17269       else if (unformat (input, "table_id %d", &dp_table))
17270         {
17271           dp_table_set = 1;
17272         }
17273       else if (unformat (input, "bd_id %d", &dp_table))
17274         {
17275           dp_table_set = 1;
17276           is_l2 = 1;
17277         }
17278       else if (unformat (input, "vni %d", &vni))
17279         {
17280           vni_set = 1;
17281         }
17282       else
17283         break;
17284     }
17285
17286   if (action_set == 0)
17287     {
17288       errmsg ("Action not set");
17289       return -99;
17290     }
17291   if (dp_table_set == 0 || vni_set == 0)
17292     {
17293       errmsg ("vni and dp_table must be set");
17294       return -99;
17295     }
17296
17297   /* Construct the API message */
17298   M (GPE_ADD_DEL_IFACE, mp);
17299
17300   mp->is_add = is_add;
17301   mp->dp_table = clib_host_to_net_u32 (dp_table);
17302   mp->is_l2 = is_l2;
17303   mp->vni = clib_host_to_net_u32 (vni);
17304
17305   /* send it... */
17306   S (mp);
17307
17308   /* Wait for a reply... */
17309   W (ret);
17310   return ret;
17311 }
17312
17313 static int
17314 api_one_map_register_fallback_threshold (vat_main_t * vam)
17315 {
17316   unformat_input_t *input = vam->input;
17317   vl_api_one_map_register_fallback_threshold_t *mp;
17318   u32 value = 0;
17319   u8 is_set = 0;
17320   int ret;
17321
17322   /* Parse args required to build the message */
17323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17324     {
17325       if (unformat (input, "%u", &value))
17326         is_set = 1;
17327       else
17328         {
17329           clib_warning ("parse error '%U'", format_unformat_error, input);
17330           return -99;
17331         }
17332     }
17333
17334   if (!is_set)
17335     {
17336       errmsg ("fallback threshold value is missing!");
17337       return -99;
17338     }
17339
17340   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17341   mp->value = clib_host_to_net_u32 (value);
17342
17343   /* send it... */
17344   S (mp);
17345
17346   /* Wait for a reply... */
17347   W (ret);
17348   return ret;
17349 }
17350
17351 static int
17352 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17353 {
17354   vl_api_show_one_map_register_fallback_threshold_t *mp;
17355   int ret;
17356
17357   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17358
17359   /* send it... */
17360   S (mp);
17361
17362   /* Wait for a reply... */
17363   W (ret);
17364   return ret;
17365 }
17366
17367 uword
17368 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17369 {
17370   u32 *proto = va_arg (*args, u32 *);
17371
17372   if (unformat (input, "udp"))
17373     *proto = 1;
17374   else if (unformat (input, "api"))
17375     *proto = 2;
17376   else
17377     return 0;
17378
17379   return 1;
17380 }
17381
17382 static int
17383 api_one_set_transport_protocol (vat_main_t * vam)
17384 {
17385   unformat_input_t *input = vam->input;
17386   vl_api_one_set_transport_protocol_t *mp;
17387   u8 is_set = 0;
17388   u32 protocol = 0;
17389   int ret;
17390
17391   /* Parse args required to build the message */
17392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17393     {
17394       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17395         is_set = 1;
17396       else
17397         {
17398           clib_warning ("parse error '%U'", format_unformat_error, input);
17399           return -99;
17400         }
17401     }
17402
17403   if (!is_set)
17404     {
17405       errmsg ("Transport protocol missing!");
17406       return -99;
17407     }
17408
17409   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17410   mp->protocol = (u8) protocol;
17411
17412   /* send it... */
17413   S (mp);
17414
17415   /* Wait for a reply... */
17416   W (ret);
17417   return ret;
17418 }
17419
17420 static int
17421 api_one_get_transport_protocol (vat_main_t * vam)
17422 {
17423   vl_api_one_get_transport_protocol_t *mp;
17424   int ret;
17425
17426   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17427
17428   /* send it... */
17429   S (mp);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_one_map_register_set_ttl (vat_main_t * vam)
17438 {
17439   unformat_input_t *input = vam->input;
17440   vl_api_one_map_register_set_ttl_t *mp;
17441   u32 ttl = 0;
17442   u8 is_set = 0;
17443   int ret;
17444
17445   /* Parse args required to build the message */
17446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17447     {
17448       if (unformat (input, "%u", &ttl))
17449         is_set = 1;
17450       else
17451         {
17452           clib_warning ("parse error '%U'", format_unformat_error, input);
17453           return -99;
17454         }
17455     }
17456
17457   if (!is_set)
17458     {
17459       errmsg ("TTL value missing!");
17460       return -99;
17461     }
17462
17463   M (ONE_MAP_REGISTER_SET_TTL, mp);
17464   mp->ttl = clib_host_to_net_u32 (ttl);
17465
17466   /* send it... */
17467   S (mp);
17468
17469   /* Wait for a reply... */
17470   W (ret);
17471   return ret;
17472 }
17473
17474 static int
17475 api_show_one_map_register_ttl (vat_main_t * vam)
17476 {
17477   vl_api_show_one_map_register_ttl_t *mp;
17478   int ret;
17479
17480   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17481
17482   /* send it... */
17483   S (mp);
17484
17485   /* Wait for a reply... */
17486   W (ret);
17487   return ret;
17488 }
17489
17490 /**
17491  * Add/del map request itr rlocs from ONE control plane and updates
17492  *
17493  * @param vam vpp API test context
17494  * @return return code
17495  */
17496 static int
17497 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17498 {
17499   unformat_input_t *input = vam->input;
17500   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17501   u8 *locator_set_name = 0;
17502   u8 locator_set_name_set = 0;
17503   u8 is_add = 1;
17504   int ret;
17505
17506   /* Parse args required to build the message */
17507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17508     {
17509       if (unformat (input, "del"))
17510         {
17511           is_add = 0;
17512         }
17513       else if (unformat (input, "%_%v%_", &locator_set_name))
17514         {
17515           locator_set_name_set = 1;
17516         }
17517       else
17518         {
17519           clib_warning ("parse error '%U'", format_unformat_error, input);
17520           return -99;
17521         }
17522     }
17523
17524   if (is_add && !locator_set_name_set)
17525     {
17526       errmsg ("itr-rloc is not set!");
17527       return -99;
17528     }
17529
17530   if (is_add && vec_len (locator_set_name) > 64)
17531     {
17532       errmsg ("itr-rloc locator-set name too long");
17533       vec_free (locator_set_name);
17534       return -99;
17535     }
17536
17537   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17538   mp->is_add = is_add;
17539   if (is_add)
17540     {
17541       clib_memcpy (mp->locator_set_name, locator_set_name,
17542                    vec_len (locator_set_name));
17543     }
17544   else
17545     {
17546       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17547     }
17548   vec_free (locator_set_name);
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17559
17560 static int
17561 api_one_locator_dump (vat_main_t * vam)
17562 {
17563   unformat_input_t *input = vam->input;
17564   vl_api_one_locator_dump_t *mp;
17565   vl_api_control_ping_t *mp_ping;
17566   u8 is_index_set = 0, is_name_set = 0;
17567   u8 *ls_name = 0;
17568   u32 ls_index = ~0;
17569   int ret;
17570
17571   /* Parse args required to build the message */
17572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17573     {
17574       if (unformat (input, "ls_name %_%v%_", &ls_name))
17575         {
17576           is_name_set = 1;
17577         }
17578       else if (unformat (input, "ls_index %d", &ls_index))
17579         {
17580           is_index_set = 1;
17581         }
17582       else
17583         {
17584           errmsg ("parse error '%U'", format_unformat_error, input);
17585           return -99;
17586         }
17587     }
17588
17589   if (!is_index_set && !is_name_set)
17590     {
17591       errmsg ("error: expected one of index or name!");
17592       return -99;
17593     }
17594
17595   if (is_index_set && is_name_set)
17596     {
17597       errmsg ("error: only one param expected!");
17598       return -99;
17599     }
17600
17601   if (vec_len (ls_name) > 62)
17602     {
17603       errmsg ("error: locator set name too long!");
17604       return -99;
17605     }
17606
17607   if (!vam->json_output)
17608     {
17609       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17610     }
17611
17612   M (ONE_LOCATOR_DUMP, mp);
17613   mp->is_index_set = is_index_set;
17614
17615   if (is_index_set)
17616     mp->ls_index = clib_host_to_net_u32 (ls_index);
17617   else
17618     {
17619       vec_add1 (ls_name, 0);
17620       strncpy ((char *) mp->ls_name, (char *) ls_name,
17621                sizeof (mp->ls_name) - 1);
17622     }
17623
17624   /* send it... */
17625   S (mp);
17626
17627   /* Use a control ping for synchronization */
17628   MPING (CONTROL_PING, mp_ping);
17629   S (mp_ping);
17630
17631   /* Wait for a reply... */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 #define api_lisp_locator_dump api_one_locator_dump
17637
17638 static int
17639 api_one_locator_set_dump (vat_main_t * vam)
17640 {
17641   vl_api_one_locator_set_dump_t *mp;
17642   vl_api_control_ping_t *mp_ping;
17643   unformat_input_t *input = vam->input;
17644   u8 filter = 0;
17645   int ret;
17646
17647   /* Parse args required to build the message */
17648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17649     {
17650       if (unformat (input, "local"))
17651         {
17652           filter = 1;
17653         }
17654       else if (unformat (input, "remote"))
17655         {
17656           filter = 2;
17657         }
17658       else
17659         {
17660           errmsg ("parse error '%U'", format_unformat_error, input);
17661           return -99;
17662         }
17663     }
17664
17665   if (!vam->json_output)
17666     {
17667       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17668     }
17669
17670   M (ONE_LOCATOR_SET_DUMP, mp);
17671
17672   mp->filter = filter;
17673
17674   /* send it... */
17675   S (mp);
17676
17677   /* Use a control ping for synchronization */
17678   MPING (CONTROL_PING, mp_ping);
17679   S (mp_ping);
17680
17681   /* Wait for a reply... */
17682   W (ret);
17683   return ret;
17684 }
17685
17686 #define api_lisp_locator_set_dump api_one_locator_set_dump
17687
17688 static int
17689 api_one_eid_table_map_dump (vat_main_t * vam)
17690 {
17691   u8 is_l2 = 0;
17692   u8 mode_set = 0;
17693   unformat_input_t *input = vam->input;
17694   vl_api_one_eid_table_map_dump_t *mp;
17695   vl_api_control_ping_t *mp_ping;
17696   int ret;
17697
17698   /* Parse args required to build the message */
17699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17700     {
17701       if (unformat (input, "l2"))
17702         {
17703           is_l2 = 1;
17704           mode_set = 1;
17705         }
17706       else if (unformat (input, "l3"))
17707         {
17708           is_l2 = 0;
17709           mode_set = 1;
17710         }
17711       else
17712         {
17713           errmsg ("parse error '%U'", format_unformat_error, input);
17714           return -99;
17715         }
17716     }
17717
17718   if (!mode_set)
17719     {
17720       errmsg ("expected one of 'l2' or 'l3' parameter!");
17721       return -99;
17722     }
17723
17724   if (!vam->json_output)
17725     {
17726       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17727     }
17728
17729   M (ONE_EID_TABLE_MAP_DUMP, mp);
17730   mp->is_l2 = is_l2;
17731
17732   /* send it... */
17733   S (mp);
17734
17735   /* Use a control ping for synchronization */
17736   MPING (CONTROL_PING, mp_ping);
17737   S (mp_ping);
17738
17739   /* Wait for a reply... */
17740   W (ret);
17741   return ret;
17742 }
17743
17744 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17745
17746 static int
17747 api_one_eid_table_vni_dump (vat_main_t * vam)
17748 {
17749   vl_api_one_eid_table_vni_dump_t *mp;
17750   vl_api_control_ping_t *mp_ping;
17751   int ret;
17752
17753   if (!vam->json_output)
17754     {
17755       print (vam->ofp, "VNI");
17756     }
17757
17758   M (ONE_EID_TABLE_VNI_DUMP, mp);
17759
17760   /* send it... */
17761   S (mp);
17762
17763   /* Use a control ping for synchronization */
17764   MPING (CONTROL_PING, mp_ping);
17765   S (mp_ping);
17766
17767   /* Wait for a reply... */
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17773
17774 static int
17775 api_one_eid_table_dump (vat_main_t * vam)
17776 {
17777   unformat_input_t *i = vam->input;
17778   vl_api_one_eid_table_dump_t *mp;
17779   vl_api_control_ping_t *mp_ping;
17780   struct in_addr ip4;
17781   struct in6_addr ip6;
17782   u8 mac[6];
17783   u8 eid_type = ~0, eid_set = 0;
17784   u32 prefix_length = ~0, t, vni = 0;
17785   u8 filter = 0;
17786   int ret;
17787   lisp_nsh_api_t nsh;
17788
17789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17790     {
17791       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17792         {
17793           eid_set = 1;
17794           eid_type = 0;
17795           prefix_length = t;
17796         }
17797       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17798         {
17799           eid_set = 1;
17800           eid_type = 1;
17801           prefix_length = t;
17802         }
17803       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17804         {
17805           eid_set = 1;
17806           eid_type = 2;
17807         }
17808       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17809         {
17810           eid_set = 1;
17811           eid_type = 3;
17812         }
17813       else if (unformat (i, "vni %d", &t))
17814         {
17815           vni = t;
17816         }
17817       else if (unformat (i, "local"))
17818         {
17819           filter = 1;
17820         }
17821       else if (unformat (i, "remote"))
17822         {
17823           filter = 2;
17824         }
17825       else
17826         {
17827           errmsg ("parse error '%U'", format_unformat_error, i);
17828           return -99;
17829         }
17830     }
17831
17832   if (!vam->json_output)
17833     {
17834       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17835              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17836     }
17837
17838   M (ONE_EID_TABLE_DUMP, mp);
17839
17840   mp->filter = filter;
17841   if (eid_set)
17842     {
17843       mp->eid_set = 1;
17844       mp->vni = htonl (vni);
17845       mp->eid_type = eid_type;
17846       switch (eid_type)
17847         {
17848         case 0:
17849           mp->prefix_length = prefix_length;
17850           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17851           break;
17852         case 1:
17853           mp->prefix_length = prefix_length;
17854           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17855           break;
17856         case 2:
17857           clib_memcpy (mp->eid, mac, sizeof (mac));
17858           break;
17859         case 3:
17860           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17861           break;
17862         default:
17863           errmsg ("unknown EID type %d!", eid_type);
17864           return -99;
17865         }
17866     }
17867
17868   /* send it... */
17869   S (mp);
17870
17871   /* Use a control ping for synchronization */
17872   MPING (CONTROL_PING, mp_ping);
17873   S (mp_ping);
17874
17875   /* Wait for a reply... */
17876   W (ret);
17877   return ret;
17878 }
17879
17880 #define api_lisp_eid_table_dump api_one_eid_table_dump
17881
17882 static int
17883 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17884 {
17885   unformat_input_t *i = vam->input;
17886   vl_api_gpe_fwd_entries_get_t *mp;
17887   u8 vni_set = 0;
17888   u32 vni = ~0;
17889   int ret;
17890
17891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17892     {
17893       if (unformat (i, "vni %d", &vni))
17894         {
17895           vni_set = 1;
17896         }
17897       else
17898         {
17899           errmsg ("parse error '%U'", format_unformat_error, i);
17900           return -99;
17901         }
17902     }
17903
17904   if (!vni_set)
17905     {
17906       errmsg ("vni not set!");
17907       return -99;
17908     }
17909
17910   if (!vam->json_output)
17911     {
17912       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17913              "leid", "reid");
17914     }
17915
17916   M (GPE_FWD_ENTRIES_GET, mp);
17917   mp->vni = clib_host_to_net_u32 (vni);
17918
17919   /* send it... */
17920   S (mp);
17921
17922   /* Wait for a reply... */
17923   W (ret);
17924   return ret;
17925 }
17926
17927 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17928 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17929 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17930 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17931 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17932 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17933 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17934 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17935
17936 static int
17937 api_one_adjacencies_get (vat_main_t * vam)
17938 {
17939   unformat_input_t *i = vam->input;
17940   vl_api_one_adjacencies_get_t *mp;
17941   u8 vni_set = 0;
17942   u32 vni = ~0;
17943   int ret;
17944
17945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17946     {
17947       if (unformat (i, "vni %d", &vni))
17948         {
17949           vni_set = 1;
17950         }
17951       else
17952         {
17953           errmsg ("parse error '%U'", format_unformat_error, i);
17954           return -99;
17955         }
17956     }
17957
17958   if (!vni_set)
17959     {
17960       errmsg ("vni not set!");
17961       return -99;
17962     }
17963
17964   if (!vam->json_output)
17965     {
17966       print (vam->ofp, "%s %40s", "leid", "reid");
17967     }
17968
17969   M (ONE_ADJACENCIES_GET, mp);
17970   mp->vni = clib_host_to_net_u32 (vni);
17971
17972   /* send it... */
17973   S (mp);
17974
17975   /* Wait for a reply... */
17976   W (ret);
17977   return ret;
17978 }
17979
17980 #define api_lisp_adjacencies_get api_one_adjacencies_get
17981
17982 static int
17983 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17984 {
17985   unformat_input_t *i = vam->input;
17986   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17987   int ret;
17988   u8 ip_family_set = 0, is_ip4 = 1;
17989
17990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17991     {
17992       if (unformat (i, "ip4"))
17993         {
17994           ip_family_set = 1;
17995           is_ip4 = 1;
17996         }
17997       else if (unformat (i, "ip6"))
17998         {
17999           ip_family_set = 1;
18000           is_ip4 = 0;
18001         }
18002       else
18003         {
18004           errmsg ("parse error '%U'", format_unformat_error, i);
18005           return -99;
18006         }
18007     }
18008
18009   if (!ip_family_set)
18010     {
18011       errmsg ("ip family not set!");
18012       return -99;
18013     }
18014
18015   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18016   mp->is_ip4 = is_ip4;
18017
18018   /* send it... */
18019   S (mp);
18020
18021   /* Wait for a reply... */
18022   W (ret);
18023   return ret;
18024 }
18025
18026 static int
18027 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18028 {
18029   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18030   int ret;
18031
18032   if (!vam->json_output)
18033     {
18034       print (vam->ofp, "VNIs");
18035     }
18036
18037   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18038
18039   /* send it... */
18040   S (mp);
18041
18042   /* Wait for a reply... */
18043   W (ret);
18044   return ret;
18045 }
18046
18047 static int
18048 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18049 {
18050   unformat_input_t *i = vam->input;
18051   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18052   int ret = 0;
18053   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18054   struct in_addr ip4;
18055   struct in6_addr ip6;
18056   u32 table_id = 0, nh_sw_if_index = ~0;
18057
18058   memset (&ip4, 0, sizeof (ip4));
18059   memset (&ip6, 0, sizeof (ip6));
18060
18061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18062     {
18063       if (unformat (i, "del"))
18064         is_add = 0;
18065       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18066                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18067         {
18068           ip_set = 1;
18069           is_ip4 = 1;
18070         }
18071       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18072                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18073         {
18074           ip_set = 1;
18075           is_ip4 = 0;
18076         }
18077       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18078         {
18079           ip_set = 1;
18080           is_ip4 = 1;
18081           nh_sw_if_index = ~0;
18082         }
18083       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18084         {
18085           ip_set = 1;
18086           is_ip4 = 0;
18087           nh_sw_if_index = ~0;
18088         }
18089       else if (unformat (i, "table %d", &table_id))
18090         ;
18091       else
18092         {
18093           errmsg ("parse error '%U'", format_unformat_error, i);
18094           return -99;
18095         }
18096     }
18097
18098   if (!ip_set)
18099     {
18100       errmsg ("nh addr not set!");
18101       return -99;
18102     }
18103
18104   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18105   mp->is_add = is_add;
18106   mp->table_id = clib_host_to_net_u32 (table_id);
18107   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18108   mp->is_ip4 = is_ip4;
18109   if (is_ip4)
18110     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18111   else
18112     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18113
18114   /* send it... */
18115   S (mp);
18116
18117   /* Wait for a reply... */
18118   W (ret);
18119   return ret;
18120 }
18121
18122 static int
18123 api_one_map_server_dump (vat_main_t * vam)
18124 {
18125   vl_api_one_map_server_dump_t *mp;
18126   vl_api_control_ping_t *mp_ping;
18127   int ret;
18128
18129   if (!vam->json_output)
18130     {
18131       print (vam->ofp, "%=20s", "Map server");
18132     }
18133
18134   M (ONE_MAP_SERVER_DUMP, mp);
18135   /* send it... */
18136   S (mp);
18137
18138   /* Use a control ping for synchronization */
18139   MPING (CONTROL_PING, mp_ping);
18140   S (mp_ping);
18141
18142   /* Wait for a reply... */
18143   W (ret);
18144   return ret;
18145 }
18146
18147 #define api_lisp_map_server_dump api_one_map_server_dump
18148
18149 static int
18150 api_one_map_resolver_dump (vat_main_t * vam)
18151 {
18152   vl_api_one_map_resolver_dump_t *mp;
18153   vl_api_control_ping_t *mp_ping;
18154   int ret;
18155
18156   if (!vam->json_output)
18157     {
18158       print (vam->ofp, "%=20s", "Map resolver");
18159     }
18160
18161   M (ONE_MAP_RESOLVER_DUMP, mp);
18162   /* send it... */
18163   S (mp);
18164
18165   /* Use a control ping for synchronization */
18166   MPING (CONTROL_PING, mp_ping);
18167   S (mp_ping);
18168
18169   /* Wait for a reply... */
18170   W (ret);
18171   return ret;
18172 }
18173
18174 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18175
18176 static int
18177 api_one_stats_flush (vat_main_t * vam)
18178 {
18179   vl_api_one_stats_flush_t *mp;
18180   int ret = 0;
18181
18182   M (ONE_STATS_FLUSH, mp);
18183   S (mp);
18184   W (ret);
18185   return ret;
18186 }
18187
18188 static int
18189 api_one_stats_dump (vat_main_t * vam)
18190 {
18191   vl_api_one_stats_dump_t *mp;
18192   vl_api_control_ping_t *mp_ping;
18193   int ret;
18194
18195   M (ONE_STATS_DUMP, mp);
18196   /* send it... */
18197   S (mp);
18198
18199   /* Use a control ping for synchronization */
18200   MPING (CONTROL_PING, mp_ping);
18201   S (mp_ping);
18202
18203   /* Wait for a reply... */
18204   W (ret);
18205   return ret;
18206 }
18207
18208 static int
18209 api_show_one_status (vat_main_t * vam)
18210 {
18211   vl_api_show_one_status_t *mp;
18212   int ret;
18213
18214   if (!vam->json_output)
18215     {
18216       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18217     }
18218
18219   M (SHOW_ONE_STATUS, mp);
18220   /* send it... */
18221   S (mp);
18222   /* Wait for a reply... */
18223   W (ret);
18224   return ret;
18225 }
18226
18227 #define api_show_lisp_status api_show_one_status
18228
18229 static int
18230 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18231 {
18232   vl_api_gpe_fwd_entry_path_dump_t *mp;
18233   vl_api_control_ping_t *mp_ping;
18234   unformat_input_t *i = vam->input;
18235   u32 fwd_entry_index = ~0;
18236   int ret;
18237
18238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18239     {
18240       if (unformat (i, "index %d", &fwd_entry_index))
18241         ;
18242       else
18243         break;
18244     }
18245
18246   if (~0 == fwd_entry_index)
18247     {
18248       errmsg ("no index specified!");
18249       return -99;
18250     }
18251
18252   if (!vam->json_output)
18253     {
18254       print (vam->ofp, "first line");
18255     }
18256
18257   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18258
18259   /* send it... */
18260   S (mp);
18261   /* Use a control ping for synchronization */
18262   MPING (CONTROL_PING, mp_ping);
18263   S (mp_ping);
18264
18265   /* Wait for a reply... */
18266   W (ret);
18267   return ret;
18268 }
18269
18270 static int
18271 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18272 {
18273   vl_api_one_get_map_request_itr_rlocs_t *mp;
18274   int ret;
18275
18276   if (!vam->json_output)
18277     {
18278       print (vam->ofp, "%=20s", "itr-rlocs:");
18279     }
18280
18281   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18282   /* send it... */
18283   S (mp);
18284   /* Wait for a reply... */
18285   W (ret);
18286   return ret;
18287 }
18288
18289 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18290
18291 static int
18292 api_af_packet_create (vat_main_t * vam)
18293 {
18294   unformat_input_t *i = vam->input;
18295   vl_api_af_packet_create_t *mp;
18296   u8 *host_if_name = 0;
18297   u8 hw_addr[6];
18298   u8 random_hw_addr = 1;
18299   int ret;
18300
18301   memset (hw_addr, 0, sizeof (hw_addr));
18302
18303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18304     {
18305       if (unformat (i, "name %s", &host_if_name))
18306         vec_add1 (host_if_name, 0);
18307       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18308         random_hw_addr = 0;
18309       else
18310         break;
18311     }
18312
18313   if (!vec_len (host_if_name))
18314     {
18315       errmsg ("host-interface name must be specified");
18316       return -99;
18317     }
18318
18319   if (vec_len (host_if_name) > 64)
18320     {
18321       errmsg ("host-interface name too long");
18322       return -99;
18323     }
18324
18325   M (AF_PACKET_CREATE, mp);
18326
18327   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18328   clib_memcpy (mp->hw_addr, hw_addr, 6);
18329   mp->use_random_hw_addr = random_hw_addr;
18330   vec_free (host_if_name);
18331
18332   S (mp);
18333
18334   /* *INDENT-OFF* */
18335   W2 (ret,
18336       ({
18337         if (ret == 0)
18338           fprintf (vam->ofp ? vam->ofp : stderr,
18339                    " new sw_if_index = %d\n", vam->sw_if_index);
18340       }));
18341   /* *INDENT-ON* */
18342   return ret;
18343 }
18344
18345 static int
18346 api_af_packet_delete (vat_main_t * vam)
18347 {
18348   unformat_input_t *i = vam->input;
18349   vl_api_af_packet_delete_t *mp;
18350   u8 *host_if_name = 0;
18351   int ret;
18352
18353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18354     {
18355       if (unformat (i, "name %s", &host_if_name))
18356         vec_add1 (host_if_name, 0);
18357       else
18358         break;
18359     }
18360
18361   if (!vec_len (host_if_name))
18362     {
18363       errmsg ("host-interface name must be specified");
18364       return -99;
18365     }
18366
18367   if (vec_len (host_if_name) > 64)
18368     {
18369       errmsg ("host-interface name too long");
18370       return -99;
18371     }
18372
18373   M (AF_PACKET_DELETE, mp);
18374
18375   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18376   vec_free (host_if_name);
18377
18378   S (mp);
18379   W (ret);
18380   return ret;
18381 }
18382
18383 static int
18384 api_policer_add_del (vat_main_t * vam)
18385 {
18386   unformat_input_t *i = vam->input;
18387   vl_api_policer_add_del_t *mp;
18388   u8 is_add = 1;
18389   u8 *name = 0;
18390   u32 cir = 0;
18391   u32 eir = 0;
18392   u64 cb = 0;
18393   u64 eb = 0;
18394   u8 rate_type = 0;
18395   u8 round_type = 0;
18396   u8 type = 0;
18397   u8 color_aware = 0;
18398   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18399   int ret;
18400
18401   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18402   conform_action.dscp = 0;
18403   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18404   exceed_action.dscp = 0;
18405   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18406   violate_action.dscp = 0;
18407
18408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18409     {
18410       if (unformat (i, "del"))
18411         is_add = 0;
18412       else if (unformat (i, "name %s", &name))
18413         vec_add1 (name, 0);
18414       else if (unformat (i, "cir %u", &cir))
18415         ;
18416       else if (unformat (i, "eir %u", &eir))
18417         ;
18418       else if (unformat (i, "cb %u", &cb))
18419         ;
18420       else if (unformat (i, "eb %u", &eb))
18421         ;
18422       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18423                          &rate_type))
18424         ;
18425       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18426                          &round_type))
18427         ;
18428       else if (unformat (i, "type %U", unformat_policer_type, &type))
18429         ;
18430       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18431                          &conform_action))
18432         ;
18433       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18434                          &exceed_action))
18435         ;
18436       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18437                          &violate_action))
18438         ;
18439       else if (unformat (i, "color-aware"))
18440         color_aware = 1;
18441       else
18442         break;
18443     }
18444
18445   if (!vec_len (name))
18446     {
18447       errmsg ("policer name must be specified");
18448       return -99;
18449     }
18450
18451   if (vec_len (name) > 64)
18452     {
18453       errmsg ("policer name too long");
18454       return -99;
18455     }
18456
18457   M (POLICER_ADD_DEL, mp);
18458
18459   clib_memcpy (mp->name, name, vec_len (name));
18460   vec_free (name);
18461   mp->is_add = is_add;
18462   mp->cir = ntohl (cir);
18463   mp->eir = ntohl (eir);
18464   mp->cb = clib_net_to_host_u64 (cb);
18465   mp->eb = clib_net_to_host_u64 (eb);
18466   mp->rate_type = rate_type;
18467   mp->round_type = round_type;
18468   mp->type = type;
18469   mp->conform_action_type = conform_action.action_type;
18470   mp->conform_dscp = conform_action.dscp;
18471   mp->exceed_action_type = exceed_action.action_type;
18472   mp->exceed_dscp = exceed_action.dscp;
18473   mp->violate_action_type = violate_action.action_type;
18474   mp->violate_dscp = violate_action.dscp;
18475   mp->color_aware = color_aware;
18476
18477   S (mp);
18478   W (ret);
18479   return ret;
18480 }
18481
18482 static int
18483 api_policer_dump (vat_main_t * vam)
18484 {
18485   unformat_input_t *i = vam->input;
18486   vl_api_policer_dump_t *mp;
18487   vl_api_control_ping_t *mp_ping;
18488   u8 *match_name = 0;
18489   u8 match_name_valid = 0;
18490   int ret;
18491
18492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (i, "name %s", &match_name))
18495         {
18496           vec_add1 (match_name, 0);
18497           match_name_valid = 1;
18498         }
18499       else
18500         break;
18501     }
18502
18503   M (POLICER_DUMP, mp);
18504   mp->match_name_valid = match_name_valid;
18505   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18506   vec_free (match_name);
18507   /* send it... */
18508   S (mp);
18509
18510   /* Use a control ping for synchronization */
18511   MPING (CONTROL_PING, mp_ping);
18512   S (mp_ping);
18513
18514   /* Wait for a reply... */
18515   W (ret);
18516   return ret;
18517 }
18518
18519 static int
18520 api_policer_classify_set_interface (vat_main_t * vam)
18521 {
18522   unformat_input_t *i = vam->input;
18523   vl_api_policer_classify_set_interface_t *mp;
18524   u32 sw_if_index;
18525   int sw_if_index_set;
18526   u32 ip4_table_index = ~0;
18527   u32 ip6_table_index = ~0;
18528   u32 l2_table_index = ~0;
18529   u8 is_add = 1;
18530   int ret;
18531
18532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18533     {
18534       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18535         sw_if_index_set = 1;
18536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18537         sw_if_index_set = 1;
18538       else if (unformat (i, "del"))
18539         is_add = 0;
18540       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18541         ;
18542       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18543         ;
18544       else if (unformat (i, "l2-table %d", &l2_table_index))
18545         ;
18546       else
18547         {
18548           clib_warning ("parse error '%U'", format_unformat_error, i);
18549           return -99;
18550         }
18551     }
18552
18553   if (sw_if_index_set == 0)
18554     {
18555       errmsg ("missing interface name or sw_if_index");
18556       return -99;
18557     }
18558
18559   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18560
18561   mp->sw_if_index = ntohl (sw_if_index);
18562   mp->ip4_table_index = ntohl (ip4_table_index);
18563   mp->ip6_table_index = ntohl (ip6_table_index);
18564   mp->l2_table_index = ntohl (l2_table_index);
18565   mp->is_add = is_add;
18566
18567   S (mp);
18568   W (ret);
18569   return ret;
18570 }
18571
18572 static int
18573 api_policer_classify_dump (vat_main_t * vam)
18574 {
18575   unformat_input_t *i = vam->input;
18576   vl_api_policer_classify_dump_t *mp;
18577   vl_api_control_ping_t *mp_ping;
18578   u8 type = POLICER_CLASSIFY_N_TABLES;
18579   int ret;
18580
18581   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18582     ;
18583   else
18584     {
18585       errmsg ("classify table type must be specified");
18586       return -99;
18587     }
18588
18589   if (!vam->json_output)
18590     {
18591       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18592     }
18593
18594   M (POLICER_CLASSIFY_DUMP, mp);
18595   mp->type = type;
18596   /* send it... */
18597   S (mp);
18598
18599   /* Use a control ping for synchronization */
18600   MPING (CONTROL_PING, mp_ping);
18601   S (mp_ping);
18602
18603   /* Wait for a reply... */
18604   W (ret);
18605   return ret;
18606 }
18607
18608 static int
18609 api_netmap_create (vat_main_t * vam)
18610 {
18611   unformat_input_t *i = vam->input;
18612   vl_api_netmap_create_t *mp;
18613   u8 *if_name = 0;
18614   u8 hw_addr[6];
18615   u8 random_hw_addr = 1;
18616   u8 is_pipe = 0;
18617   u8 is_master = 0;
18618   int ret;
18619
18620   memset (hw_addr, 0, sizeof (hw_addr));
18621
18622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18623     {
18624       if (unformat (i, "name %s", &if_name))
18625         vec_add1 (if_name, 0);
18626       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18627         random_hw_addr = 0;
18628       else if (unformat (i, "pipe"))
18629         is_pipe = 1;
18630       else if (unformat (i, "master"))
18631         is_master = 1;
18632       else if (unformat (i, "slave"))
18633         is_master = 0;
18634       else
18635         break;
18636     }
18637
18638   if (!vec_len (if_name))
18639     {
18640       errmsg ("interface name must be specified");
18641       return -99;
18642     }
18643
18644   if (vec_len (if_name) > 64)
18645     {
18646       errmsg ("interface name too long");
18647       return -99;
18648     }
18649
18650   M (NETMAP_CREATE, mp);
18651
18652   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18653   clib_memcpy (mp->hw_addr, hw_addr, 6);
18654   mp->use_random_hw_addr = random_hw_addr;
18655   mp->is_pipe = is_pipe;
18656   mp->is_master = is_master;
18657   vec_free (if_name);
18658
18659   S (mp);
18660   W (ret);
18661   return ret;
18662 }
18663
18664 static int
18665 api_netmap_delete (vat_main_t * vam)
18666 {
18667   unformat_input_t *i = vam->input;
18668   vl_api_netmap_delete_t *mp;
18669   u8 *if_name = 0;
18670   int ret;
18671
18672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18673     {
18674       if (unformat (i, "name %s", &if_name))
18675         vec_add1 (if_name, 0);
18676       else
18677         break;
18678     }
18679
18680   if (!vec_len (if_name))
18681     {
18682       errmsg ("interface name must be specified");
18683       return -99;
18684     }
18685
18686   if (vec_len (if_name) > 64)
18687     {
18688       errmsg ("interface name too long");
18689       return -99;
18690     }
18691
18692   M (NETMAP_DELETE, mp);
18693
18694   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18695   vec_free (if_name);
18696
18697   S (mp);
18698   W (ret);
18699   return ret;
18700 }
18701
18702 static void
18703 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18704 {
18705   if (fp->afi == IP46_TYPE_IP6)
18706     print (vam->ofp,
18707            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18708            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18709            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18710            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18711            format_ip6_address, fp->next_hop);
18712   else if (fp->afi == IP46_TYPE_IP4)
18713     print (vam->ofp,
18714            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18715            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18716            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18717            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18718            format_ip4_address, fp->next_hop);
18719 }
18720
18721 static void
18722 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18723                                  vl_api_fib_path2_t * fp)
18724 {
18725   struct in_addr ip4;
18726   struct in6_addr ip6;
18727
18728   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18729   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18730   vat_json_object_add_uint (node, "is_local", fp->is_local);
18731   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18732   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18733   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18734   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18735   if (fp->afi == IP46_TYPE_IP4)
18736     {
18737       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18738       vat_json_object_add_ip4 (node, "next_hop", ip4);
18739     }
18740   else if (fp->afi == IP46_TYPE_IP6)
18741     {
18742       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18743       vat_json_object_add_ip6 (node, "next_hop", ip6);
18744     }
18745 }
18746
18747 static void
18748 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18749 {
18750   vat_main_t *vam = &vat_main;
18751   int count = ntohl (mp->mt_count);
18752   vl_api_fib_path2_t *fp;
18753   i32 i;
18754
18755   print (vam->ofp, "[%d]: sw_if_index %d via:",
18756          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18757   fp = mp->mt_paths;
18758   for (i = 0; i < count; i++)
18759     {
18760       vl_api_mpls_fib_path_print (vam, fp);
18761       fp++;
18762     }
18763
18764   print (vam->ofp, "");
18765 }
18766
18767 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18768 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18769
18770 static void
18771 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18772 {
18773   vat_main_t *vam = &vat_main;
18774   vat_json_node_t *node = NULL;
18775   int count = ntohl (mp->mt_count);
18776   vl_api_fib_path2_t *fp;
18777   i32 i;
18778
18779   if (VAT_JSON_ARRAY != vam->json_tree.type)
18780     {
18781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18782       vat_json_init_array (&vam->json_tree);
18783     }
18784   node = vat_json_array_add (&vam->json_tree);
18785
18786   vat_json_init_object (node);
18787   vat_json_object_add_uint (node, "tunnel_index",
18788                             ntohl (mp->mt_tunnel_index));
18789   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18790
18791   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18792
18793   fp = mp->mt_paths;
18794   for (i = 0; i < count; i++)
18795     {
18796       vl_api_mpls_fib_path_json_print (node, fp);
18797       fp++;
18798     }
18799 }
18800
18801 static int
18802 api_mpls_tunnel_dump (vat_main_t * vam)
18803 {
18804   vl_api_mpls_tunnel_dump_t *mp;
18805   vl_api_control_ping_t *mp_ping;
18806   i32 index = -1;
18807   int ret;
18808
18809   /* Parse args required to build the message */
18810   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18811     {
18812       if (!unformat (vam->input, "tunnel_index %d", &index))
18813         {
18814           index = -1;
18815           break;
18816         }
18817     }
18818
18819   print (vam->ofp, "  tunnel_index %d", index);
18820
18821   M (MPLS_TUNNEL_DUMP, mp);
18822   mp->tunnel_index = htonl (index);
18823   S (mp);
18824
18825   /* Use a control ping for synchronization */
18826   MPING (CONTROL_PING, mp_ping);
18827   S (mp_ping);
18828
18829   W (ret);
18830   return ret;
18831 }
18832
18833 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18834 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18835
18836
18837 static void
18838 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18839 {
18840   vat_main_t *vam = &vat_main;
18841   int count = ntohl (mp->count);
18842   vl_api_fib_path2_t *fp;
18843   int i;
18844
18845   print (vam->ofp,
18846          "table-id %d, label %u, ess_bit %u",
18847          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18848   fp = mp->path;
18849   for (i = 0; i < count; i++)
18850     {
18851       vl_api_mpls_fib_path_print (vam, fp);
18852       fp++;
18853     }
18854 }
18855
18856 static void vl_api_mpls_fib_details_t_handler_json
18857   (vl_api_mpls_fib_details_t * mp)
18858 {
18859   vat_main_t *vam = &vat_main;
18860   int count = ntohl (mp->count);
18861   vat_json_node_t *node = NULL;
18862   vl_api_fib_path2_t *fp;
18863   int i;
18864
18865   if (VAT_JSON_ARRAY != vam->json_tree.type)
18866     {
18867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18868       vat_json_init_array (&vam->json_tree);
18869     }
18870   node = vat_json_array_add (&vam->json_tree);
18871
18872   vat_json_init_object (node);
18873   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18874   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18875   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18876   vat_json_object_add_uint (node, "path_count", count);
18877   fp = mp->path;
18878   for (i = 0; i < count; i++)
18879     {
18880       vl_api_mpls_fib_path_json_print (node, fp);
18881       fp++;
18882     }
18883 }
18884
18885 static int
18886 api_mpls_fib_dump (vat_main_t * vam)
18887 {
18888   vl_api_mpls_fib_dump_t *mp;
18889   vl_api_control_ping_t *mp_ping;
18890   int ret;
18891
18892   M (MPLS_FIB_DUMP, mp);
18893   S (mp);
18894
18895   /* Use a control ping for synchronization */
18896   MPING (CONTROL_PING, mp_ping);
18897   S (mp_ping);
18898
18899   W (ret);
18900   return ret;
18901 }
18902
18903 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18904 #define vl_api_ip_fib_details_t_print vl_noop_handler
18905
18906 static void
18907 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18908 {
18909   vat_main_t *vam = &vat_main;
18910   int count = ntohl (mp->count);
18911   vl_api_fib_path_t *fp;
18912   int i;
18913
18914   print (vam->ofp,
18915          "table-id %d, prefix %U/%d",
18916          ntohl (mp->table_id), format_ip4_address, mp->address,
18917          mp->address_length);
18918   fp = mp->path;
18919   for (i = 0; i < count; i++)
18920     {
18921       if (fp->afi == IP46_TYPE_IP6)
18922         print (vam->ofp,
18923                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18924                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18925                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18926                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18927                format_ip6_address, fp->next_hop);
18928       else if (fp->afi == IP46_TYPE_IP4)
18929         print (vam->ofp,
18930                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18931                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18932                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18933                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18934                format_ip4_address, fp->next_hop);
18935       fp++;
18936     }
18937 }
18938
18939 static void vl_api_ip_fib_details_t_handler_json
18940   (vl_api_ip_fib_details_t * mp)
18941 {
18942   vat_main_t *vam = &vat_main;
18943   int count = ntohl (mp->count);
18944   vat_json_node_t *node = NULL;
18945   struct in_addr ip4;
18946   struct in6_addr ip6;
18947   vl_api_fib_path_t *fp;
18948   int i;
18949
18950   if (VAT_JSON_ARRAY != vam->json_tree.type)
18951     {
18952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18953       vat_json_init_array (&vam->json_tree);
18954     }
18955   node = vat_json_array_add (&vam->json_tree);
18956
18957   vat_json_init_object (node);
18958   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18959   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18960   vat_json_object_add_ip4 (node, "prefix", ip4);
18961   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18962   vat_json_object_add_uint (node, "path_count", count);
18963   fp = mp->path;
18964   for (i = 0; i < count; i++)
18965     {
18966       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18967       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18968       vat_json_object_add_uint (node, "is_local", fp->is_local);
18969       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18970       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18971       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18972       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18973       if (fp->afi == IP46_TYPE_IP4)
18974         {
18975           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18976           vat_json_object_add_ip4 (node, "next_hop", ip4);
18977         }
18978       else if (fp->afi == IP46_TYPE_IP6)
18979         {
18980           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18981           vat_json_object_add_ip6 (node, "next_hop", ip6);
18982         }
18983     }
18984 }
18985
18986 static int
18987 api_ip_fib_dump (vat_main_t * vam)
18988 {
18989   vl_api_ip_fib_dump_t *mp;
18990   vl_api_control_ping_t *mp_ping;
18991   int ret;
18992
18993   M (IP_FIB_DUMP, mp);
18994   S (mp);
18995
18996   /* Use a control ping for synchronization */
18997   MPING (CONTROL_PING, mp_ping);
18998   S (mp_ping);
18999
19000   W (ret);
19001   return ret;
19002 }
19003
19004 static int
19005 api_ip_mfib_dump (vat_main_t * vam)
19006 {
19007   vl_api_ip_mfib_dump_t *mp;
19008   vl_api_control_ping_t *mp_ping;
19009   int ret;
19010
19011   M (IP_MFIB_DUMP, mp);
19012   S (mp);
19013
19014   /* Use a control ping for synchronization */
19015   MPING (CONTROL_PING, mp_ping);
19016   S (mp_ping);
19017
19018   W (ret);
19019   return ret;
19020 }
19021
19022 static void vl_api_ip_neighbor_details_t_handler
19023   (vl_api_ip_neighbor_details_t * mp)
19024 {
19025   vat_main_t *vam = &vat_main;
19026
19027   print (vam->ofp, "%c %U %U",
19028          (mp->is_static) ? 'S' : 'D',
19029          format_ethernet_address, &mp->mac_address,
19030          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19031          &mp->ip_address);
19032 }
19033
19034 static void vl_api_ip_neighbor_details_t_handler_json
19035   (vl_api_ip_neighbor_details_t * mp)
19036 {
19037
19038   vat_main_t *vam = &vat_main;
19039   vat_json_node_t *node;
19040   struct in_addr ip4;
19041   struct in6_addr ip6;
19042
19043   if (VAT_JSON_ARRAY != vam->json_tree.type)
19044     {
19045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19046       vat_json_init_array (&vam->json_tree);
19047     }
19048   node = vat_json_array_add (&vam->json_tree);
19049
19050   vat_json_init_object (node);
19051   vat_json_object_add_string_copy (node, "flag",
19052                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19053                                    "dynamic");
19054
19055   vat_json_object_add_string_copy (node, "link_layer",
19056                                    format (0, "%U", format_ethernet_address,
19057                                            &mp->mac_address));
19058
19059   if (mp->is_ipv6)
19060     {
19061       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19062       vat_json_object_add_ip6 (node, "ip_address", ip6);
19063     }
19064   else
19065     {
19066       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19067       vat_json_object_add_ip4 (node, "ip_address", ip4);
19068     }
19069 }
19070
19071 static int
19072 api_ip_neighbor_dump (vat_main_t * vam)
19073 {
19074   unformat_input_t *i = vam->input;
19075   vl_api_ip_neighbor_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   u8 is_ipv6 = 0;
19078   u32 sw_if_index = ~0;
19079   int ret;
19080
19081   /* Parse args required to build the message */
19082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19083     {
19084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19085         ;
19086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19087         ;
19088       else if (unformat (i, "ip6"))
19089         is_ipv6 = 1;
19090       else
19091         break;
19092     }
19093
19094   if (sw_if_index == ~0)
19095     {
19096       errmsg ("missing interface name or sw_if_index");
19097       return -99;
19098     }
19099
19100   M (IP_NEIGHBOR_DUMP, mp);
19101   mp->is_ipv6 = (u8) is_ipv6;
19102   mp->sw_if_index = ntohl (sw_if_index);
19103   S (mp);
19104
19105   /* Use a control ping for synchronization */
19106   MPING (CONTROL_PING, mp_ping);
19107   S (mp_ping);
19108
19109   W (ret);
19110   return ret;
19111 }
19112
19113 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19114 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19115
19116 static void
19117 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19118 {
19119   vat_main_t *vam = &vat_main;
19120   int count = ntohl (mp->count);
19121   vl_api_fib_path_t *fp;
19122   int i;
19123
19124   print (vam->ofp,
19125          "table-id %d, prefix %U/%d",
19126          ntohl (mp->table_id), format_ip6_address, mp->address,
19127          mp->address_length);
19128   fp = mp->path;
19129   for (i = 0; i < count; i++)
19130     {
19131       if (fp->afi == IP46_TYPE_IP6)
19132         print (vam->ofp,
19133                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19134                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19135                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19136                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19137                format_ip6_address, fp->next_hop);
19138       else if (fp->afi == IP46_TYPE_IP4)
19139         print (vam->ofp,
19140                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19141                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19142                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19143                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19144                format_ip4_address, fp->next_hop);
19145       fp++;
19146     }
19147 }
19148
19149 static void vl_api_ip6_fib_details_t_handler_json
19150   (vl_api_ip6_fib_details_t * mp)
19151 {
19152   vat_main_t *vam = &vat_main;
19153   int count = ntohl (mp->count);
19154   vat_json_node_t *node = NULL;
19155   struct in_addr ip4;
19156   struct in6_addr ip6;
19157   vl_api_fib_path_t *fp;
19158   int i;
19159
19160   if (VAT_JSON_ARRAY != vam->json_tree.type)
19161     {
19162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19163       vat_json_init_array (&vam->json_tree);
19164     }
19165   node = vat_json_array_add (&vam->json_tree);
19166
19167   vat_json_init_object (node);
19168   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19169   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19170   vat_json_object_add_ip6 (node, "prefix", ip6);
19171   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19172   vat_json_object_add_uint (node, "path_count", count);
19173   fp = mp->path;
19174   for (i = 0; i < count; i++)
19175     {
19176       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19177       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19178       vat_json_object_add_uint (node, "is_local", fp->is_local);
19179       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19180       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19181       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19182       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19183       if (fp->afi == IP46_TYPE_IP4)
19184         {
19185           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19186           vat_json_object_add_ip4 (node, "next_hop", ip4);
19187         }
19188       else if (fp->afi == IP46_TYPE_IP6)
19189         {
19190           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19191           vat_json_object_add_ip6 (node, "next_hop", ip6);
19192         }
19193     }
19194 }
19195
19196 static int
19197 api_ip6_fib_dump (vat_main_t * vam)
19198 {
19199   vl_api_ip6_fib_dump_t *mp;
19200   vl_api_control_ping_t *mp_ping;
19201   int ret;
19202
19203   M (IP6_FIB_DUMP, mp);
19204   S (mp);
19205
19206   /* Use a control ping for synchronization */
19207   MPING (CONTROL_PING, mp_ping);
19208   S (mp_ping);
19209
19210   W (ret);
19211   return ret;
19212 }
19213
19214 static int
19215 api_ip6_mfib_dump (vat_main_t * vam)
19216 {
19217   vl_api_ip6_mfib_dump_t *mp;
19218   vl_api_control_ping_t *mp_ping;
19219   int ret;
19220
19221   M (IP6_MFIB_DUMP, mp);
19222   S (mp);
19223
19224   /* Use a control ping for synchronization */
19225   MPING (CONTROL_PING, mp_ping);
19226   S (mp_ping);
19227
19228   W (ret);
19229   return ret;
19230 }
19231
19232 int
19233 api_classify_table_ids (vat_main_t * vam)
19234 {
19235   vl_api_classify_table_ids_t *mp;
19236   int ret;
19237
19238   /* Construct the API message */
19239   M (CLASSIFY_TABLE_IDS, mp);
19240   mp->context = 0;
19241
19242   S (mp);
19243   W (ret);
19244   return ret;
19245 }
19246
19247 int
19248 api_classify_table_by_interface (vat_main_t * vam)
19249 {
19250   unformat_input_t *input = vam->input;
19251   vl_api_classify_table_by_interface_t *mp;
19252
19253   u32 sw_if_index = ~0;
19254   int ret;
19255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19256     {
19257       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19258         ;
19259       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19260         ;
19261       else
19262         break;
19263     }
19264   if (sw_if_index == ~0)
19265     {
19266       errmsg ("missing interface name or sw_if_index");
19267       return -99;
19268     }
19269
19270   /* Construct the API message */
19271   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19272   mp->context = 0;
19273   mp->sw_if_index = ntohl (sw_if_index);
19274
19275   S (mp);
19276   W (ret);
19277   return ret;
19278 }
19279
19280 int
19281 api_classify_table_info (vat_main_t * vam)
19282 {
19283   unformat_input_t *input = vam->input;
19284   vl_api_classify_table_info_t *mp;
19285
19286   u32 table_id = ~0;
19287   int ret;
19288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19289     {
19290       if (unformat (input, "table_id %d", &table_id))
19291         ;
19292       else
19293         break;
19294     }
19295   if (table_id == ~0)
19296     {
19297       errmsg ("missing table id");
19298       return -99;
19299     }
19300
19301   /* Construct the API message */
19302   M (CLASSIFY_TABLE_INFO, mp);
19303   mp->context = 0;
19304   mp->table_id = ntohl (table_id);
19305
19306   S (mp);
19307   W (ret);
19308   return ret;
19309 }
19310
19311 int
19312 api_classify_session_dump (vat_main_t * vam)
19313 {
19314   unformat_input_t *input = vam->input;
19315   vl_api_classify_session_dump_t *mp;
19316   vl_api_control_ping_t *mp_ping;
19317
19318   u32 table_id = ~0;
19319   int ret;
19320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19321     {
19322       if (unformat (input, "table_id %d", &table_id))
19323         ;
19324       else
19325         break;
19326     }
19327   if (table_id == ~0)
19328     {
19329       errmsg ("missing table id");
19330       return -99;
19331     }
19332
19333   /* Construct the API message */
19334   M (CLASSIFY_SESSION_DUMP, mp);
19335   mp->context = 0;
19336   mp->table_id = ntohl (table_id);
19337   S (mp);
19338
19339   /* Use a control ping for synchronization */
19340   MPING (CONTROL_PING, mp_ping);
19341   S (mp_ping);
19342
19343   W (ret);
19344   return ret;
19345 }
19346
19347 static void
19348 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19349 {
19350   vat_main_t *vam = &vat_main;
19351
19352   print (vam->ofp, "collector_address %U, collector_port %d, "
19353          "src_address %U, vrf_id %d, path_mtu %u, "
19354          "template_interval %u, udp_checksum %d",
19355          format_ip4_address, mp->collector_address,
19356          ntohs (mp->collector_port),
19357          format_ip4_address, mp->src_address,
19358          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19359          ntohl (mp->template_interval), mp->udp_checksum);
19360
19361   vam->retval = 0;
19362   vam->result_ready = 1;
19363 }
19364
19365 static void
19366   vl_api_ipfix_exporter_details_t_handler_json
19367   (vl_api_ipfix_exporter_details_t * mp)
19368 {
19369   vat_main_t *vam = &vat_main;
19370   vat_json_node_t node;
19371   struct in_addr collector_address;
19372   struct in_addr src_address;
19373
19374   vat_json_init_object (&node);
19375   clib_memcpy (&collector_address, &mp->collector_address,
19376                sizeof (collector_address));
19377   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19378   vat_json_object_add_uint (&node, "collector_port",
19379                             ntohs (mp->collector_port));
19380   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19381   vat_json_object_add_ip4 (&node, "src_address", src_address);
19382   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19383   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19384   vat_json_object_add_uint (&node, "template_interval",
19385                             ntohl (mp->template_interval));
19386   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19387
19388   vat_json_print (vam->ofp, &node);
19389   vat_json_free (&node);
19390   vam->retval = 0;
19391   vam->result_ready = 1;
19392 }
19393
19394 int
19395 api_ipfix_exporter_dump (vat_main_t * vam)
19396 {
19397   vl_api_ipfix_exporter_dump_t *mp;
19398   int ret;
19399
19400   /* Construct the API message */
19401   M (IPFIX_EXPORTER_DUMP, mp);
19402   mp->context = 0;
19403
19404   S (mp);
19405   W (ret);
19406   return ret;
19407 }
19408
19409 static int
19410 api_ipfix_classify_stream_dump (vat_main_t * vam)
19411 {
19412   vl_api_ipfix_classify_stream_dump_t *mp;
19413   int ret;
19414
19415   /* Construct the API message */
19416   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19417   mp->context = 0;
19418
19419   S (mp);
19420   W (ret);
19421   return ret;
19422   /* NOTREACHED */
19423   return 0;
19424 }
19425
19426 static void
19427   vl_api_ipfix_classify_stream_details_t_handler
19428   (vl_api_ipfix_classify_stream_details_t * mp)
19429 {
19430   vat_main_t *vam = &vat_main;
19431   print (vam->ofp, "domain_id %d, src_port %d",
19432          ntohl (mp->domain_id), ntohs (mp->src_port));
19433   vam->retval = 0;
19434   vam->result_ready = 1;
19435 }
19436
19437 static void
19438   vl_api_ipfix_classify_stream_details_t_handler_json
19439   (vl_api_ipfix_classify_stream_details_t * mp)
19440 {
19441   vat_main_t *vam = &vat_main;
19442   vat_json_node_t node;
19443
19444   vat_json_init_object (&node);
19445   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19446   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19447
19448   vat_json_print (vam->ofp, &node);
19449   vat_json_free (&node);
19450   vam->retval = 0;
19451   vam->result_ready = 1;
19452 }
19453
19454 static int
19455 api_ipfix_classify_table_dump (vat_main_t * vam)
19456 {
19457   vl_api_ipfix_classify_table_dump_t *mp;
19458   vl_api_control_ping_t *mp_ping;
19459   int ret;
19460
19461   if (!vam->json_output)
19462     {
19463       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19464              "transport_protocol");
19465     }
19466
19467   /* Construct the API message */
19468   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19469
19470   /* send it... */
19471   S (mp);
19472
19473   /* Use a control ping for synchronization */
19474   MPING (CONTROL_PING, mp_ping);
19475   S (mp_ping);
19476
19477   W (ret);
19478   return ret;
19479 }
19480
19481 static void
19482   vl_api_ipfix_classify_table_details_t_handler
19483   (vl_api_ipfix_classify_table_details_t * mp)
19484 {
19485   vat_main_t *vam = &vat_main;
19486   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19487          mp->transport_protocol);
19488 }
19489
19490 static void
19491   vl_api_ipfix_classify_table_details_t_handler_json
19492   (vl_api_ipfix_classify_table_details_t * mp)
19493 {
19494   vat_json_node_t *node = NULL;
19495   vat_main_t *vam = &vat_main;
19496
19497   if (VAT_JSON_ARRAY != vam->json_tree.type)
19498     {
19499       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19500       vat_json_init_array (&vam->json_tree);
19501     }
19502
19503   node = vat_json_array_add (&vam->json_tree);
19504   vat_json_init_object (node);
19505
19506   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19507   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19508   vat_json_object_add_uint (node, "transport_protocol",
19509                             mp->transport_protocol);
19510 }
19511
19512 static int
19513 api_sw_interface_span_enable_disable (vat_main_t * vam)
19514 {
19515   unformat_input_t *i = vam->input;
19516   vl_api_sw_interface_span_enable_disable_t *mp;
19517   u32 src_sw_if_index = ~0;
19518   u32 dst_sw_if_index = ~0;
19519   u8 state = 3;
19520   int ret;
19521   u8 is_l2 = 0;
19522
19523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19524     {
19525       if (unformat
19526           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19527         ;
19528       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19529         ;
19530       else
19531         if (unformat
19532             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19533         ;
19534       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19535         ;
19536       else if (unformat (i, "disable"))
19537         state = 0;
19538       else if (unformat (i, "rx"))
19539         state = 1;
19540       else if (unformat (i, "tx"))
19541         state = 2;
19542       else if (unformat (i, "both"))
19543         state = 3;
19544       else if (unformat (i, "l2"))
19545         is_l2 = 1;
19546       else
19547         break;
19548     }
19549
19550   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19551
19552   mp->sw_if_index_from = htonl (src_sw_if_index);
19553   mp->sw_if_index_to = htonl (dst_sw_if_index);
19554   mp->state = state;
19555   mp->is_l2 = is_l2;
19556
19557   S (mp);
19558   W (ret);
19559   return ret;
19560 }
19561
19562 static void
19563 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19564                                             * mp)
19565 {
19566   vat_main_t *vam = &vat_main;
19567   u8 *sw_if_from_name = 0;
19568   u8 *sw_if_to_name = 0;
19569   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19570   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19571   char *states[] = { "none", "rx", "tx", "both" };
19572   hash_pair_t *p;
19573
19574   /* *INDENT-OFF* */
19575   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19576   ({
19577     if ((u32) p->value[0] == sw_if_index_from)
19578       {
19579         sw_if_from_name = (u8 *)(p->key);
19580         if (sw_if_to_name)
19581           break;
19582       }
19583     if ((u32) p->value[0] == sw_if_index_to)
19584       {
19585         sw_if_to_name = (u8 *)(p->key);
19586         if (sw_if_from_name)
19587           break;
19588       }
19589   }));
19590   /* *INDENT-ON* */
19591   print (vam->ofp, "%20s => %20s (%s)",
19592          sw_if_from_name, sw_if_to_name, states[mp->state]);
19593 }
19594
19595 static void
19596   vl_api_sw_interface_span_details_t_handler_json
19597   (vl_api_sw_interface_span_details_t * mp)
19598 {
19599   vat_main_t *vam = &vat_main;
19600   vat_json_node_t *node = NULL;
19601   u8 *sw_if_from_name = 0;
19602   u8 *sw_if_to_name = 0;
19603   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19604   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19605   hash_pair_t *p;
19606
19607   /* *INDENT-OFF* */
19608   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19609   ({
19610     if ((u32) p->value[0] == sw_if_index_from)
19611       {
19612         sw_if_from_name = (u8 *)(p->key);
19613         if (sw_if_to_name)
19614           break;
19615       }
19616     if ((u32) p->value[0] == sw_if_index_to)
19617       {
19618         sw_if_to_name = (u8 *)(p->key);
19619         if (sw_if_from_name)
19620           break;
19621       }
19622   }));
19623   /* *INDENT-ON* */
19624
19625   if (VAT_JSON_ARRAY != vam->json_tree.type)
19626     {
19627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19628       vat_json_init_array (&vam->json_tree);
19629     }
19630   node = vat_json_array_add (&vam->json_tree);
19631
19632   vat_json_init_object (node);
19633   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19634   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19635   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19636   if (0 != sw_if_to_name)
19637     {
19638       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19639     }
19640   vat_json_object_add_uint (node, "state", mp->state);
19641 }
19642
19643 static int
19644 api_sw_interface_span_dump (vat_main_t * vam)
19645 {
19646   unformat_input_t *input = vam->input;
19647   vl_api_sw_interface_span_dump_t *mp;
19648   vl_api_control_ping_t *mp_ping;
19649   u8 is_l2 = 0;
19650   int ret;
19651
19652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19653     {
19654       if (unformat (input, "l2"))
19655         is_l2 = 1;
19656       else
19657         break;
19658     }
19659
19660   M (SW_INTERFACE_SPAN_DUMP, mp);
19661   mp->is_l2 = is_l2;
19662   S (mp);
19663
19664   /* Use a control ping for synchronization */
19665   MPING (CONTROL_PING, mp_ping);
19666   S (mp_ping);
19667
19668   W (ret);
19669   return ret;
19670 }
19671
19672 int
19673 api_pg_create_interface (vat_main_t * vam)
19674 {
19675   unformat_input_t *input = vam->input;
19676   vl_api_pg_create_interface_t *mp;
19677
19678   u32 if_id = ~0;
19679   int ret;
19680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19681     {
19682       if (unformat (input, "if_id %d", &if_id))
19683         ;
19684       else
19685         break;
19686     }
19687   if (if_id == ~0)
19688     {
19689       errmsg ("missing pg interface index");
19690       return -99;
19691     }
19692
19693   /* Construct the API message */
19694   M (PG_CREATE_INTERFACE, mp);
19695   mp->context = 0;
19696   mp->interface_id = ntohl (if_id);
19697
19698   S (mp);
19699   W (ret);
19700   return ret;
19701 }
19702
19703 int
19704 api_pg_capture (vat_main_t * vam)
19705 {
19706   unformat_input_t *input = vam->input;
19707   vl_api_pg_capture_t *mp;
19708
19709   u32 if_id = ~0;
19710   u8 enable = 1;
19711   u32 count = 1;
19712   u8 pcap_file_set = 0;
19713   u8 *pcap_file = 0;
19714   int ret;
19715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19716     {
19717       if (unformat (input, "if_id %d", &if_id))
19718         ;
19719       else if (unformat (input, "pcap %s", &pcap_file))
19720         pcap_file_set = 1;
19721       else if (unformat (input, "count %d", &count))
19722         ;
19723       else if (unformat (input, "disable"))
19724         enable = 0;
19725       else
19726         break;
19727     }
19728   if (if_id == ~0)
19729     {
19730       errmsg ("missing pg interface index");
19731       return -99;
19732     }
19733   if (pcap_file_set > 0)
19734     {
19735       if (vec_len (pcap_file) > 255)
19736         {
19737           errmsg ("pcap file name is too long");
19738           return -99;
19739         }
19740     }
19741
19742   u32 name_len = vec_len (pcap_file);
19743   /* Construct the API message */
19744   M (PG_CAPTURE, mp);
19745   mp->context = 0;
19746   mp->interface_id = ntohl (if_id);
19747   mp->is_enabled = enable;
19748   mp->count = ntohl (count);
19749   mp->pcap_name_length = ntohl (name_len);
19750   if (pcap_file_set != 0)
19751     {
19752       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19753     }
19754   vec_free (pcap_file);
19755
19756   S (mp);
19757   W (ret);
19758   return ret;
19759 }
19760
19761 int
19762 api_pg_enable_disable (vat_main_t * vam)
19763 {
19764   unformat_input_t *input = vam->input;
19765   vl_api_pg_enable_disable_t *mp;
19766
19767   u8 enable = 1;
19768   u8 stream_name_set = 0;
19769   u8 *stream_name = 0;
19770   int ret;
19771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19772     {
19773       if (unformat (input, "stream %s", &stream_name))
19774         stream_name_set = 1;
19775       else if (unformat (input, "disable"))
19776         enable = 0;
19777       else
19778         break;
19779     }
19780
19781   if (stream_name_set > 0)
19782     {
19783       if (vec_len (stream_name) > 255)
19784         {
19785           errmsg ("stream name too long");
19786           return -99;
19787         }
19788     }
19789
19790   u32 name_len = vec_len (stream_name);
19791   /* Construct the API message */
19792   M (PG_ENABLE_DISABLE, mp);
19793   mp->context = 0;
19794   mp->is_enabled = enable;
19795   if (stream_name_set != 0)
19796     {
19797       mp->stream_name_length = ntohl (name_len);
19798       clib_memcpy (mp->stream_name, stream_name, name_len);
19799     }
19800   vec_free (stream_name);
19801
19802   S (mp);
19803   W (ret);
19804   return ret;
19805 }
19806
19807 int
19808 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19809 {
19810   unformat_input_t *input = vam->input;
19811   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19812
19813   u16 *low_ports = 0;
19814   u16 *high_ports = 0;
19815   u16 this_low;
19816   u16 this_hi;
19817   ip4_address_t ip4_addr;
19818   ip6_address_t ip6_addr;
19819   u32 length;
19820   u32 tmp, tmp2;
19821   u8 prefix_set = 0;
19822   u32 vrf_id = ~0;
19823   u8 is_add = 1;
19824   u8 is_ipv6 = 0;
19825   int ret;
19826
19827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19828     {
19829       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19830         {
19831           prefix_set = 1;
19832         }
19833       else
19834         if (unformat
19835             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19836         {
19837           prefix_set = 1;
19838           is_ipv6 = 1;
19839         }
19840       else if (unformat (input, "vrf %d", &vrf_id))
19841         ;
19842       else if (unformat (input, "del"))
19843         is_add = 0;
19844       else if (unformat (input, "port %d", &tmp))
19845         {
19846           if (tmp == 0 || tmp > 65535)
19847             {
19848               errmsg ("port %d out of range", tmp);
19849               return -99;
19850             }
19851           this_low = tmp;
19852           this_hi = this_low + 1;
19853           vec_add1 (low_ports, this_low);
19854           vec_add1 (high_ports, this_hi);
19855         }
19856       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19857         {
19858           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19859             {
19860               errmsg ("incorrect range parameters");
19861               return -99;
19862             }
19863           this_low = tmp;
19864           /* Note: in debug CLI +1 is added to high before
19865              passing to real fn that does "the work"
19866              (ip_source_and_port_range_check_add_del).
19867              This fn is a wrapper around the binary API fn a
19868              control plane will call, which expects this increment
19869              to have occurred. Hence letting the binary API control
19870              plane fn do the increment for consistency between VAT
19871              and other control planes.
19872            */
19873           this_hi = tmp2;
19874           vec_add1 (low_ports, this_low);
19875           vec_add1 (high_ports, this_hi);
19876         }
19877       else
19878         break;
19879     }
19880
19881   if (prefix_set == 0)
19882     {
19883       errmsg ("<address>/<mask> not specified");
19884       return -99;
19885     }
19886
19887   if (vrf_id == ~0)
19888     {
19889       errmsg ("VRF ID required, not specified");
19890       return -99;
19891     }
19892
19893   if (vrf_id == 0)
19894     {
19895       errmsg
19896         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19897       return -99;
19898     }
19899
19900   if (vec_len (low_ports) == 0)
19901     {
19902       errmsg ("At least one port or port range required");
19903       return -99;
19904     }
19905
19906   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19907
19908   mp->is_add = is_add;
19909
19910   if (is_ipv6)
19911     {
19912       mp->is_ipv6 = 1;
19913       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19914     }
19915   else
19916     {
19917       mp->is_ipv6 = 0;
19918       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19919     }
19920
19921   mp->mask_length = length;
19922   mp->number_of_ranges = vec_len (low_ports);
19923
19924   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19925   vec_free (low_ports);
19926
19927   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19928   vec_free (high_ports);
19929
19930   mp->vrf_id = ntohl (vrf_id);
19931
19932   S (mp);
19933   W (ret);
19934   return ret;
19935 }
19936
19937 int
19938 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19939 {
19940   unformat_input_t *input = vam->input;
19941   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19942   u32 sw_if_index = ~0;
19943   int vrf_set = 0;
19944   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19945   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19946   u8 is_add = 1;
19947   int ret;
19948
19949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19950     {
19951       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19952         ;
19953       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19954         ;
19955       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19956         vrf_set = 1;
19957       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19958         vrf_set = 1;
19959       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19960         vrf_set = 1;
19961       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19962         vrf_set = 1;
19963       else if (unformat (input, "del"))
19964         is_add = 0;
19965       else
19966         break;
19967     }
19968
19969   if (sw_if_index == ~0)
19970     {
19971       errmsg ("Interface required but not specified");
19972       return -99;
19973     }
19974
19975   if (vrf_set == 0)
19976     {
19977       errmsg ("VRF ID required but not specified");
19978       return -99;
19979     }
19980
19981   if (tcp_out_vrf_id == 0
19982       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19983     {
19984       errmsg
19985         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19986       return -99;
19987     }
19988
19989   /* Construct the API message */
19990   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19991
19992   mp->sw_if_index = ntohl (sw_if_index);
19993   mp->is_add = is_add;
19994   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19995   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19996   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19997   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19998
19999   /* send it... */
20000   S (mp);
20001
20002   /* Wait for a reply... */
20003   W (ret);
20004   return ret;
20005 }
20006
20007 static int
20008 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20009 {
20010   unformat_input_t *i = vam->input;
20011   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20012   u32 local_sa_id = 0;
20013   u32 remote_sa_id = 0;
20014   ip4_address_t src_address;
20015   ip4_address_t dst_address;
20016   u8 is_add = 1;
20017   int ret;
20018
20019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20020     {
20021       if (unformat (i, "local_sa %d", &local_sa_id))
20022         ;
20023       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20024         ;
20025       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20026         ;
20027       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20028         ;
20029       else if (unformat (i, "del"))
20030         is_add = 0;
20031       else
20032         {
20033           clib_warning ("parse error '%U'", format_unformat_error, i);
20034           return -99;
20035         }
20036     }
20037
20038   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20039
20040   mp->local_sa_id = ntohl (local_sa_id);
20041   mp->remote_sa_id = ntohl (remote_sa_id);
20042   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20043   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20044   mp->is_add = is_add;
20045
20046   S (mp);
20047   W (ret);
20048   return ret;
20049 }
20050
20051 static int
20052 api_punt (vat_main_t * vam)
20053 {
20054   unformat_input_t *i = vam->input;
20055   vl_api_punt_t *mp;
20056   u32 ipv = ~0;
20057   u32 protocol = ~0;
20058   u32 port = ~0;
20059   int is_add = 1;
20060   int ret;
20061
20062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20063     {
20064       if (unformat (i, "ip %d", &ipv))
20065         ;
20066       else if (unformat (i, "protocol %d", &protocol))
20067         ;
20068       else if (unformat (i, "port %d", &port))
20069         ;
20070       else if (unformat (i, "del"))
20071         is_add = 0;
20072       else
20073         {
20074           clib_warning ("parse error '%U'", format_unformat_error, i);
20075           return -99;
20076         }
20077     }
20078
20079   M (PUNT, mp);
20080
20081   mp->is_add = (u8) is_add;
20082   mp->ipv = (u8) ipv;
20083   mp->l4_protocol = (u8) protocol;
20084   mp->l4_port = htons ((u16) port);
20085
20086   S (mp);
20087   W (ret);
20088   return ret;
20089 }
20090
20091 static void vl_api_ipsec_gre_tunnel_details_t_handler
20092   (vl_api_ipsec_gre_tunnel_details_t * mp)
20093 {
20094   vat_main_t *vam = &vat_main;
20095
20096   print (vam->ofp, "%11d%15U%15U%14d%14d",
20097          ntohl (mp->sw_if_index),
20098          format_ip4_address, &mp->src_address,
20099          format_ip4_address, &mp->dst_address,
20100          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20101 }
20102
20103 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20104   (vl_api_ipsec_gre_tunnel_details_t * mp)
20105 {
20106   vat_main_t *vam = &vat_main;
20107   vat_json_node_t *node = NULL;
20108   struct in_addr ip4;
20109
20110   if (VAT_JSON_ARRAY != vam->json_tree.type)
20111     {
20112       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20113       vat_json_init_array (&vam->json_tree);
20114     }
20115   node = vat_json_array_add (&vam->json_tree);
20116
20117   vat_json_init_object (node);
20118   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20119   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20120   vat_json_object_add_ip4 (node, "src_address", ip4);
20121   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20122   vat_json_object_add_ip4 (node, "dst_address", ip4);
20123   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20124   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20125 }
20126
20127 static int
20128 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20129 {
20130   unformat_input_t *i = vam->input;
20131   vl_api_ipsec_gre_tunnel_dump_t *mp;
20132   vl_api_control_ping_t *mp_ping;
20133   u32 sw_if_index;
20134   u8 sw_if_index_set = 0;
20135   int ret;
20136
20137   /* Parse args required to build the message */
20138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20139     {
20140       if (unformat (i, "sw_if_index %d", &sw_if_index))
20141         sw_if_index_set = 1;
20142       else
20143         break;
20144     }
20145
20146   if (sw_if_index_set == 0)
20147     {
20148       sw_if_index = ~0;
20149     }
20150
20151   if (!vam->json_output)
20152     {
20153       print (vam->ofp, "%11s%15s%15s%14s%14s",
20154              "sw_if_index", "src_address", "dst_address",
20155              "local_sa_id", "remote_sa_id");
20156     }
20157
20158   /* Get list of gre-tunnel interfaces */
20159   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20160
20161   mp->sw_if_index = htonl (sw_if_index);
20162
20163   S (mp);
20164
20165   /* Use a control ping for synchronization */
20166   MPING (CONTROL_PING, mp_ping);
20167   S (mp_ping);
20168
20169   W (ret);
20170   return ret;
20171 }
20172
20173 static int
20174 api_delete_subif (vat_main_t * vam)
20175 {
20176   unformat_input_t *i = vam->input;
20177   vl_api_delete_subif_t *mp;
20178   u32 sw_if_index = ~0;
20179   int ret;
20180
20181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20182     {
20183       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20184         ;
20185       if (unformat (i, "sw_if_index %d", &sw_if_index))
20186         ;
20187       else
20188         break;
20189     }
20190
20191   if (sw_if_index == ~0)
20192     {
20193       errmsg ("missing sw_if_index");
20194       return -99;
20195     }
20196
20197   /* Construct the API message */
20198   M (DELETE_SUBIF, mp);
20199   mp->sw_if_index = ntohl (sw_if_index);
20200
20201   S (mp);
20202   W (ret);
20203   return ret;
20204 }
20205
20206 #define foreach_pbb_vtr_op      \
20207 _("disable",  L2_VTR_DISABLED)  \
20208 _("pop",  L2_VTR_POP_2)         \
20209 _("push",  L2_VTR_PUSH_2)
20210
20211 static int
20212 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20213 {
20214   unformat_input_t *i = vam->input;
20215   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20216   u32 sw_if_index = ~0, vtr_op = ~0;
20217   u16 outer_tag = ~0;
20218   u8 dmac[6], smac[6];
20219   u8 dmac_set = 0, smac_set = 0;
20220   u16 vlanid = 0;
20221   u32 sid = ~0;
20222   u32 tmp;
20223   int ret;
20224
20225   /* Shut up coverity */
20226   memset (dmac, 0, sizeof (dmac));
20227   memset (smac, 0, sizeof (smac));
20228
20229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20230     {
20231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20232         ;
20233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20234         ;
20235       else if (unformat (i, "vtr_op %d", &vtr_op))
20236         ;
20237 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20238       foreach_pbb_vtr_op
20239 #undef _
20240         else if (unformat (i, "translate_pbb_stag"))
20241         {
20242           if (unformat (i, "%d", &tmp))
20243             {
20244               vtr_op = L2_VTR_TRANSLATE_2_1;
20245               outer_tag = tmp;
20246             }
20247           else
20248             {
20249               errmsg
20250                 ("translate_pbb_stag operation requires outer tag definition");
20251               return -99;
20252             }
20253         }
20254       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20255         dmac_set++;
20256       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20257         smac_set++;
20258       else if (unformat (i, "sid %d", &sid))
20259         ;
20260       else if (unformat (i, "vlanid %d", &tmp))
20261         vlanid = tmp;
20262       else
20263         {
20264           clib_warning ("parse error '%U'", format_unformat_error, i);
20265           return -99;
20266         }
20267     }
20268
20269   if ((sw_if_index == ~0) || (vtr_op == ~0))
20270     {
20271       errmsg ("missing sw_if_index or vtr operation");
20272       return -99;
20273     }
20274   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20275       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20276     {
20277       errmsg
20278         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20279       return -99;
20280     }
20281
20282   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20283   mp->sw_if_index = ntohl (sw_if_index);
20284   mp->vtr_op = ntohl (vtr_op);
20285   mp->outer_tag = ntohs (outer_tag);
20286   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20287   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20288   mp->b_vlanid = ntohs (vlanid);
20289   mp->i_sid = ntohl (sid);
20290
20291   S (mp);
20292   W (ret);
20293   return ret;
20294 }
20295
20296 static int
20297 api_flow_classify_set_interface (vat_main_t * vam)
20298 {
20299   unformat_input_t *i = vam->input;
20300   vl_api_flow_classify_set_interface_t *mp;
20301   u32 sw_if_index;
20302   int sw_if_index_set;
20303   u32 ip4_table_index = ~0;
20304   u32 ip6_table_index = ~0;
20305   u8 is_add = 1;
20306   int ret;
20307
20308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20309     {
20310       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20311         sw_if_index_set = 1;
20312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20313         sw_if_index_set = 1;
20314       else if (unformat (i, "del"))
20315         is_add = 0;
20316       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20317         ;
20318       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20319         ;
20320       else
20321         {
20322           clib_warning ("parse error '%U'", format_unformat_error, i);
20323           return -99;
20324         }
20325     }
20326
20327   if (sw_if_index_set == 0)
20328     {
20329       errmsg ("missing interface name or sw_if_index");
20330       return -99;
20331     }
20332
20333   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20334
20335   mp->sw_if_index = ntohl (sw_if_index);
20336   mp->ip4_table_index = ntohl (ip4_table_index);
20337   mp->ip6_table_index = ntohl (ip6_table_index);
20338   mp->is_add = is_add;
20339
20340   S (mp);
20341   W (ret);
20342   return ret;
20343 }
20344
20345 static int
20346 api_flow_classify_dump (vat_main_t * vam)
20347 {
20348   unformat_input_t *i = vam->input;
20349   vl_api_flow_classify_dump_t *mp;
20350   vl_api_control_ping_t *mp_ping;
20351   u8 type = FLOW_CLASSIFY_N_TABLES;
20352   int ret;
20353
20354   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20355     ;
20356   else
20357     {
20358       errmsg ("classify table type must be specified");
20359       return -99;
20360     }
20361
20362   if (!vam->json_output)
20363     {
20364       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20365     }
20366
20367   M (FLOW_CLASSIFY_DUMP, mp);
20368   mp->type = type;
20369   /* send it... */
20370   S (mp);
20371
20372   /* Use a control ping for synchronization */
20373   MPING (CONTROL_PING, mp_ping);
20374   S (mp_ping);
20375
20376   /* Wait for a reply... */
20377   W (ret);
20378   return ret;
20379 }
20380
20381 static int
20382 api_feature_enable_disable (vat_main_t * vam)
20383 {
20384   unformat_input_t *i = vam->input;
20385   vl_api_feature_enable_disable_t *mp;
20386   u8 *arc_name = 0;
20387   u8 *feature_name = 0;
20388   u32 sw_if_index = ~0;
20389   u8 enable = 1;
20390   int ret;
20391
20392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20393     {
20394       if (unformat (i, "arc_name %s", &arc_name))
20395         ;
20396       else if (unformat (i, "feature_name %s", &feature_name))
20397         ;
20398       else
20399         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20400         ;
20401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20402         ;
20403       else if (unformat (i, "disable"))
20404         enable = 0;
20405       else
20406         break;
20407     }
20408
20409   if (arc_name == 0)
20410     {
20411       errmsg ("missing arc name");
20412       return -99;
20413     }
20414   if (vec_len (arc_name) > 63)
20415     {
20416       errmsg ("arc name too long");
20417     }
20418
20419   if (feature_name == 0)
20420     {
20421       errmsg ("missing feature name");
20422       return -99;
20423     }
20424   if (vec_len (feature_name) > 63)
20425     {
20426       errmsg ("feature name too long");
20427     }
20428
20429   if (sw_if_index == ~0)
20430     {
20431       errmsg ("missing interface name or sw_if_index");
20432       return -99;
20433     }
20434
20435   /* Construct the API message */
20436   M (FEATURE_ENABLE_DISABLE, mp);
20437   mp->sw_if_index = ntohl (sw_if_index);
20438   mp->enable = enable;
20439   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20440   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20441   vec_free (arc_name);
20442   vec_free (feature_name);
20443
20444   S (mp);
20445   W (ret);
20446   return ret;
20447 }
20448
20449 static int
20450 api_sw_interface_tag_add_del (vat_main_t * vam)
20451 {
20452   unformat_input_t *i = vam->input;
20453   vl_api_sw_interface_tag_add_del_t *mp;
20454   u32 sw_if_index = ~0;
20455   u8 *tag = 0;
20456   u8 enable = 1;
20457   int ret;
20458
20459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20460     {
20461       if (unformat (i, "tag %s", &tag))
20462         ;
20463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20464         ;
20465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20466         ;
20467       else if (unformat (i, "del"))
20468         enable = 0;
20469       else
20470         break;
20471     }
20472
20473   if (sw_if_index == ~0)
20474     {
20475       errmsg ("missing interface name or sw_if_index");
20476       return -99;
20477     }
20478
20479   if (enable && (tag == 0))
20480     {
20481       errmsg ("no tag specified");
20482       return -99;
20483     }
20484
20485   /* Construct the API message */
20486   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20487   mp->sw_if_index = ntohl (sw_if_index);
20488   mp->is_add = enable;
20489   if (enable)
20490     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20491   vec_free (tag);
20492
20493   S (mp);
20494   W (ret);
20495   return ret;
20496 }
20497
20498 static void vl_api_l2_xconnect_details_t_handler
20499   (vl_api_l2_xconnect_details_t * mp)
20500 {
20501   vat_main_t *vam = &vat_main;
20502
20503   print (vam->ofp, "%15d%15d",
20504          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20505 }
20506
20507 static void vl_api_l2_xconnect_details_t_handler_json
20508   (vl_api_l2_xconnect_details_t * mp)
20509 {
20510   vat_main_t *vam = &vat_main;
20511   vat_json_node_t *node = NULL;
20512
20513   if (VAT_JSON_ARRAY != vam->json_tree.type)
20514     {
20515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20516       vat_json_init_array (&vam->json_tree);
20517     }
20518   node = vat_json_array_add (&vam->json_tree);
20519
20520   vat_json_init_object (node);
20521   vat_json_object_add_uint (node, "rx_sw_if_index",
20522                             ntohl (mp->rx_sw_if_index));
20523   vat_json_object_add_uint (node, "tx_sw_if_index",
20524                             ntohl (mp->tx_sw_if_index));
20525 }
20526
20527 static int
20528 api_l2_xconnect_dump (vat_main_t * vam)
20529 {
20530   vl_api_l2_xconnect_dump_t *mp;
20531   vl_api_control_ping_t *mp_ping;
20532   int ret;
20533
20534   if (!vam->json_output)
20535     {
20536       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20537     }
20538
20539   M (L2_XCONNECT_DUMP, mp);
20540
20541   S (mp);
20542
20543   /* Use a control ping for synchronization */
20544   MPING (CONTROL_PING, mp_ping);
20545   S (mp_ping);
20546
20547   W (ret);
20548   return ret;
20549 }
20550
20551 static int
20552 api_sw_interface_set_mtu (vat_main_t * vam)
20553 {
20554   unformat_input_t *i = vam->input;
20555   vl_api_sw_interface_set_mtu_t *mp;
20556   u32 sw_if_index = ~0;
20557   u32 mtu = 0;
20558   int ret;
20559
20560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20561     {
20562       if (unformat (i, "mtu %d", &mtu))
20563         ;
20564       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20565         ;
20566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20567         ;
20568       else
20569         break;
20570     }
20571
20572   if (sw_if_index == ~0)
20573     {
20574       errmsg ("missing interface name or sw_if_index");
20575       return -99;
20576     }
20577
20578   if (mtu == 0)
20579     {
20580       errmsg ("no mtu specified");
20581       return -99;
20582     }
20583
20584   /* Construct the API message */
20585   M (SW_INTERFACE_SET_MTU, mp);
20586   mp->sw_if_index = ntohl (sw_if_index);
20587   mp->mtu = ntohs ((u16) mtu);
20588
20589   S (mp);
20590   W (ret);
20591   return ret;
20592 }
20593
20594 static int
20595 api_p2p_ethernet_add (vat_main_t * vam)
20596 {
20597   unformat_input_t *i = vam->input;
20598   vl_api_p2p_ethernet_add_t *mp;
20599   u32 parent_if_index = ~0;
20600   u32 sub_id = ~0;
20601   u8 remote_mac[6];
20602   u8 mac_set = 0;
20603   int ret;
20604
20605   memset (remote_mac, 0, sizeof (remote_mac));
20606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20607     {
20608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20609         ;
20610       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20611         ;
20612       else
20613         if (unformat
20614             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20615         mac_set++;
20616       else if (unformat (i, "sub_id %d", &sub_id))
20617         ;
20618       else
20619         {
20620           clib_warning ("parse error '%U'", format_unformat_error, i);
20621           return -99;
20622         }
20623     }
20624
20625   if (parent_if_index == ~0)
20626     {
20627       errmsg ("missing interface name or sw_if_index");
20628       return -99;
20629     }
20630   if (mac_set == 0)
20631     {
20632       errmsg ("missing remote mac address");
20633       return -99;
20634     }
20635   if (sub_id == ~0)
20636     {
20637       errmsg ("missing sub-interface id");
20638       return -99;
20639     }
20640
20641   M (P2P_ETHERNET_ADD, mp);
20642   mp->parent_if_index = ntohl (parent_if_index);
20643   mp->subif_id = ntohl (sub_id);
20644   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20645
20646   S (mp);
20647   W (ret);
20648   return ret;
20649 }
20650
20651 static int
20652 api_p2p_ethernet_del (vat_main_t * vam)
20653 {
20654   unformat_input_t *i = vam->input;
20655   vl_api_p2p_ethernet_del_t *mp;
20656   u32 parent_if_index = ~0;
20657   u8 remote_mac[6];
20658   u8 mac_set = 0;
20659   int ret;
20660
20661   memset (remote_mac, 0, sizeof (remote_mac));
20662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20663     {
20664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20665         ;
20666       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20667         ;
20668       else
20669         if (unformat
20670             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20671         mac_set++;
20672       else
20673         {
20674           clib_warning ("parse error '%U'", format_unformat_error, i);
20675           return -99;
20676         }
20677     }
20678
20679   if (parent_if_index == ~0)
20680     {
20681       errmsg ("missing interface name or sw_if_index");
20682       return -99;
20683     }
20684   if (mac_set == 0)
20685     {
20686       errmsg ("missing remote mac address");
20687       return -99;
20688     }
20689
20690   M (P2P_ETHERNET_DEL, mp);
20691   mp->parent_if_index = ntohl (parent_if_index);
20692   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20693
20694   S (mp);
20695   W (ret);
20696   return ret;
20697 }
20698
20699 static int
20700 api_lldp_config (vat_main_t * vam)
20701 {
20702   unformat_input_t *i = vam->input;
20703   vl_api_lldp_config_t *mp;
20704   int tx_hold = 0;
20705   int tx_interval = 0;
20706   u8 *sys_name = NULL;
20707   int ret;
20708
20709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20710     {
20711       if (unformat (i, "system-name %s", &sys_name))
20712         ;
20713       else if (unformat (i, "tx-hold %d", &tx_hold))
20714         ;
20715       else if (unformat (i, "tx-interval %d", &tx_interval))
20716         ;
20717       else
20718         {
20719           clib_warning ("parse error '%U'", format_unformat_error, i);
20720           return -99;
20721         }
20722     }
20723
20724   vec_add1 (sys_name, 0);
20725
20726   M (LLDP_CONFIG, mp);
20727   mp->tx_hold = htonl (tx_hold);
20728   mp->tx_interval = htonl (tx_interval);
20729   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20730   vec_free (sys_name);
20731
20732   S (mp);
20733   W (ret);
20734   return ret;
20735 }
20736
20737 static int
20738 api_sw_interface_set_lldp (vat_main_t * vam)
20739 {
20740   unformat_input_t *i = vam->input;
20741   vl_api_sw_interface_set_lldp_t *mp;
20742   u32 sw_if_index = ~0;
20743   u32 enable = 1;
20744   u8 *port_desc = NULL, *mgmt_oid = NULL;
20745   ip4_address_t ip4_addr;
20746   ip6_address_t ip6_addr;
20747   int ret;
20748
20749   memset (&ip4_addr, 0, sizeof (ip4_addr));
20750   memset (&ip6_addr, 0, sizeof (ip6_addr));
20751
20752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20753     {
20754       if (unformat (i, "disable"))
20755         enable = 0;
20756       else
20757         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20758         ;
20759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20760         ;
20761       else if (unformat (i, "port-desc %s", &port_desc))
20762         ;
20763       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20764         ;
20765       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20766         ;
20767       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20768         ;
20769       else
20770         break;
20771     }
20772
20773   if (sw_if_index == ~0)
20774     {
20775       errmsg ("missing interface name or sw_if_index");
20776       return -99;
20777     }
20778
20779   /* Construct the API message */
20780   vec_add1 (port_desc, 0);
20781   vec_add1 (mgmt_oid, 0);
20782   M (SW_INTERFACE_SET_LLDP, mp);
20783   mp->sw_if_index = ntohl (sw_if_index);
20784   mp->enable = enable;
20785   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20786   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20787   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20788   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20789   vec_free (port_desc);
20790   vec_free (mgmt_oid);
20791
20792   S (mp);
20793   W (ret);
20794   return ret;
20795 }
20796
20797 static int
20798 api_tcp_configure_src_addresses (vat_main_t * vam)
20799 {
20800   vl_api_tcp_configure_src_addresses_t *mp;
20801   unformat_input_t *i = vam->input;
20802   ip4_address_t v4first, v4last;
20803   ip6_address_t v6first, v6last;
20804   u8 range_set = 0;
20805   u32 vrf_id = 0;
20806   int ret;
20807
20808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20809     {
20810       if (unformat (i, "%U - %U",
20811                     unformat_ip4_address, &v4first,
20812                     unformat_ip4_address, &v4last))
20813         {
20814           if (range_set)
20815             {
20816               errmsg ("one range per message (range already set)");
20817               return -99;
20818             }
20819           range_set = 1;
20820         }
20821       else if (unformat (i, "%U - %U",
20822                          unformat_ip6_address, &v6first,
20823                          unformat_ip6_address, &v6last))
20824         {
20825           if (range_set)
20826             {
20827               errmsg ("one range per message (range already set)");
20828               return -99;
20829             }
20830           range_set = 2;
20831         }
20832       else if (unformat (i, "vrf %d", &vrf_id))
20833         ;
20834       else
20835         break;
20836     }
20837
20838   if (range_set == 0)
20839     {
20840       errmsg ("address range not set");
20841       return -99;
20842     }
20843
20844   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20845   mp->vrf_id = ntohl (vrf_id);
20846   /* ipv6? */
20847   if (range_set == 2)
20848     {
20849       mp->is_ipv6 = 1;
20850       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20851       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20852     }
20853   else
20854     {
20855       mp->is_ipv6 = 0;
20856       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20857       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20858     }
20859   S (mp);
20860   W (ret);
20861   return ret;
20862 }
20863
20864 static int
20865 api_app_namespace_add_del (vat_main_t * vam)
20866 {
20867   vl_api_app_namespace_add_del_t *mp;
20868   unformat_input_t *i = vam->input;
20869   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20870   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20871   u64 secret;
20872   int ret;
20873
20874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20875     {
20876       if (unformat (i, "id %_%v%_", &ns_id))
20877         ;
20878       else if (unformat (i, "secret %lu", &secret))
20879         secret_set = 1;
20880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20881         sw_if_index_set = 1;
20882       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20883         ;
20884       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20885         ;
20886       else
20887         break;
20888     }
20889   if (!ns_id || !secret_set || !sw_if_index_set)
20890     {
20891       errmsg ("namespace id, secret and sw_if_index must be set");
20892       return -99;
20893     }
20894   if (vec_len (ns_id) > 64)
20895     {
20896       errmsg ("namespace id too long");
20897       return -99;
20898     }
20899   M (APP_NAMESPACE_ADD_DEL, mp);
20900
20901   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20902   mp->namespace_id_len = vec_len (ns_id);
20903   mp->secret = secret;
20904   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20905   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20906   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20907   vec_free (ns_id);
20908   S (mp);
20909   W (ret);
20910   return ret;
20911 }
20912
20913 static int
20914 api_memfd_segment_create (vat_main_t * vam)
20915 {
20916 #if VPP_API_TEST_BUILTIN == 0
20917   unformat_input_t *i = vam->input;
20918   vl_api_memfd_segment_create_t *mp;
20919   u64 size = 64 << 20;
20920   int ret;
20921
20922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20923     {
20924       if (unformat (i, "size %U", unformat_memory_size, &size))
20925         ;
20926       else
20927         break;
20928     }
20929
20930   M (MEMFD_SEGMENT_CREATE, mp);
20931   mp->requested_size = size;
20932   S (mp);
20933   W (ret);
20934   return ret;
20935
20936 #else
20937   errmsg ("memfd_segment_create (builtin) not supported");
20938   return -99;
20939 #endif
20940 }
20941
20942 static int
20943 api_dns_enable_disable (vat_main_t * vam)
20944 {
20945   unformat_input_t *line_input = vam->input;
20946   vl_api_dns_enable_disable_t *mp;
20947   u8 enable_disable = 1;
20948   int ret;
20949
20950   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20951     {
20952       if (unformat (line_input, "disable"))
20953         enable_disable = 0;
20954       if (unformat (line_input, "enable"))
20955         enable_disable = 1;
20956       else
20957         break;
20958     }
20959
20960   /* Construct the API message */
20961   M (DNS_ENABLE_DISABLE, mp);
20962   mp->enable = enable_disable;
20963
20964   /* send it... */
20965   S (mp);
20966   /* Wait for the reply */
20967   W (ret);
20968   return ret;
20969 }
20970
20971 static int
20972 api_dns_resolve_name (vat_main_t * vam)
20973 {
20974   unformat_input_t *line_input = vam->input;
20975   vl_api_dns_resolve_name_t *mp;
20976   u8 *name = 0;
20977   int ret;
20978
20979   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20980     {
20981       if (unformat (line_input, "%s", &name))
20982         ;
20983       else
20984         break;
20985     }
20986
20987   if (vec_len (name) > 127)
20988     {
20989       errmsg ("name too long");
20990       return -99;
20991     }
20992
20993   /* Construct the API message */
20994   M (DNS_RESOLVE_NAME, mp);
20995   memcpy (mp->name, name, vec_len (name));
20996   vec_free (name);
20997
20998   /* send it... */
20999   S (mp);
21000   /* Wait for the reply */
21001   W (ret);
21002   return ret;
21003 }
21004
21005 static int
21006 api_dns_name_server_add_del (vat_main_t * vam)
21007 {
21008   unformat_input_t *i = vam->input;
21009   vl_api_dns_name_server_add_del_t *mp;
21010   u8 is_add = 1;
21011   ip6_address_t ip6_server;
21012   ip4_address_t ip4_server;
21013   int ip6_set = 0;
21014   int ip4_set = 0;
21015   int ret = 0;
21016
21017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21018     {
21019       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21020         ip6_set = 1;
21021       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21022         ip4_set = 1;
21023       else if (unformat (i, "del"))
21024         is_add = 0;
21025       else
21026         {
21027           clib_warning ("parse error '%U'", format_unformat_error, i);
21028           return -99;
21029         }
21030     }
21031
21032   if (ip4_set && ip6_set)
21033     {
21034       errmsg ("Only one server address allowed per message");
21035       return -99;
21036     }
21037   if ((ip4_set + ip6_set) == 0)
21038     {
21039       errmsg ("Server address required");
21040       return -99;
21041     }
21042
21043   /* Construct the API message */
21044   M (DNS_NAME_SERVER_ADD_DEL, mp);
21045
21046   if (ip6_set)
21047     {
21048       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21049       mp->is_ip6 = 1;
21050     }
21051   else
21052     {
21053       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21054       mp->is_ip6 = 0;
21055     }
21056
21057   mp->is_add = is_add;
21058
21059   /* send it... */
21060   S (mp);
21061
21062   /* Wait for a reply, return good/bad news  */
21063   W (ret);
21064   return ret;
21065 }
21066
21067
21068 static int
21069 q_or_quit (vat_main_t * vam)
21070 {
21071 #if VPP_API_TEST_BUILTIN == 0
21072   longjmp (vam->jump_buf, 1);
21073 #endif
21074   return 0;                     /* not so much */
21075 }
21076
21077 static int
21078 q (vat_main_t * vam)
21079 {
21080   return q_or_quit (vam);
21081 }
21082
21083 static int
21084 quit (vat_main_t * vam)
21085 {
21086   return q_or_quit (vam);
21087 }
21088
21089 static int
21090 comment (vat_main_t * vam)
21091 {
21092   return 0;
21093 }
21094
21095 static int
21096 cmd_cmp (void *a1, void *a2)
21097 {
21098   u8 **c1 = a1;
21099   u8 **c2 = a2;
21100
21101   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21102 }
21103
21104 static int
21105 help (vat_main_t * vam)
21106 {
21107   u8 **cmds = 0;
21108   u8 *name = 0;
21109   hash_pair_t *p;
21110   unformat_input_t *i = vam->input;
21111   int j;
21112
21113   if (unformat (i, "%s", &name))
21114     {
21115       uword *hs;
21116
21117       vec_add1 (name, 0);
21118
21119       hs = hash_get_mem (vam->help_by_name, name);
21120       if (hs)
21121         print (vam->ofp, "usage: %s %s", name, hs[0]);
21122       else
21123         print (vam->ofp, "No such msg / command '%s'", name);
21124       vec_free (name);
21125       return 0;
21126     }
21127
21128   print (vam->ofp, "Help is available for the following:");
21129
21130     /* *INDENT-OFF* */
21131     hash_foreach_pair (p, vam->function_by_name,
21132     ({
21133       vec_add1 (cmds, (u8 *)(p->key));
21134     }));
21135     /* *INDENT-ON* */
21136
21137   vec_sort_with_function (cmds, cmd_cmp);
21138
21139   for (j = 0; j < vec_len (cmds); j++)
21140     print (vam->ofp, "%s", cmds[j]);
21141
21142   vec_free (cmds);
21143   return 0;
21144 }
21145
21146 static int
21147 set (vat_main_t * vam)
21148 {
21149   u8 *name = 0, *value = 0;
21150   unformat_input_t *i = vam->input;
21151
21152   if (unformat (i, "%s", &name))
21153     {
21154       /* The input buffer is a vector, not a string. */
21155       value = vec_dup (i->buffer);
21156       vec_delete (value, i->index, 0);
21157       /* Almost certainly has a trailing newline */
21158       if (value[vec_len (value) - 1] == '\n')
21159         value[vec_len (value) - 1] = 0;
21160       /* Make sure it's a proper string, one way or the other */
21161       vec_add1 (value, 0);
21162       (void) clib_macro_set_value (&vam->macro_main,
21163                                    (char *) name, (char *) value);
21164     }
21165   else
21166     errmsg ("usage: set <name> <value>");
21167
21168   vec_free (name);
21169   vec_free (value);
21170   return 0;
21171 }
21172
21173 static int
21174 unset (vat_main_t * vam)
21175 {
21176   u8 *name = 0;
21177
21178   if (unformat (vam->input, "%s", &name))
21179     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21180       errmsg ("unset: %s wasn't set", name);
21181   vec_free (name);
21182   return 0;
21183 }
21184
21185 typedef struct
21186 {
21187   u8 *name;
21188   u8 *value;
21189 } macro_sort_t;
21190
21191
21192 static int
21193 macro_sort_cmp (void *a1, void *a2)
21194 {
21195   macro_sort_t *s1 = a1;
21196   macro_sort_t *s2 = a2;
21197
21198   return strcmp ((char *) (s1->name), (char *) (s2->name));
21199 }
21200
21201 static int
21202 dump_macro_table (vat_main_t * vam)
21203 {
21204   macro_sort_t *sort_me = 0, *sm;
21205   int i;
21206   hash_pair_t *p;
21207
21208     /* *INDENT-OFF* */
21209     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21210     ({
21211       vec_add2 (sort_me, sm, 1);
21212       sm->name = (u8 *)(p->key);
21213       sm->value = (u8 *) (p->value[0]);
21214     }));
21215     /* *INDENT-ON* */
21216
21217   vec_sort_with_function (sort_me, macro_sort_cmp);
21218
21219   if (vec_len (sort_me))
21220     print (vam->ofp, "%-15s%s", "Name", "Value");
21221   else
21222     print (vam->ofp, "The macro table is empty...");
21223
21224   for (i = 0; i < vec_len (sort_me); i++)
21225     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21226   return 0;
21227 }
21228
21229 static int
21230 dump_node_table (vat_main_t * vam)
21231 {
21232   int i, j;
21233   vlib_node_t *node, *next_node;
21234
21235   if (vec_len (vam->graph_nodes) == 0)
21236     {
21237       print (vam->ofp, "Node table empty, issue get_node_graph...");
21238       return 0;
21239     }
21240
21241   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21242     {
21243       node = vam->graph_nodes[i];
21244       print (vam->ofp, "[%d] %s", i, node->name);
21245       for (j = 0; j < vec_len (node->next_nodes); j++)
21246         {
21247           if (node->next_nodes[j] != ~0)
21248             {
21249               next_node = vam->graph_nodes[node->next_nodes[j]];
21250               print (vam->ofp, "  [%d] %s", j, next_node->name);
21251             }
21252         }
21253     }
21254   return 0;
21255 }
21256
21257 static int
21258 value_sort_cmp (void *a1, void *a2)
21259 {
21260   name_sort_t *n1 = a1;
21261   name_sort_t *n2 = a2;
21262
21263   if (n1->value < n2->value)
21264     return -1;
21265   if (n1->value > n2->value)
21266     return 1;
21267   return 0;
21268 }
21269
21270
21271 static int
21272 dump_msg_api_table (vat_main_t * vam)
21273 {
21274   api_main_t *am = &api_main;
21275   name_sort_t *nses = 0, *ns;
21276   hash_pair_t *hp;
21277   int i;
21278
21279   /* *INDENT-OFF* */
21280   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21281   ({
21282     vec_add2 (nses, ns, 1);
21283     ns->name = (u8 *)(hp->key);
21284     ns->value = (u32) hp->value[0];
21285   }));
21286   /* *INDENT-ON* */
21287
21288   vec_sort_with_function (nses, value_sort_cmp);
21289
21290   for (i = 0; i < vec_len (nses); i++)
21291     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21292   vec_free (nses);
21293   return 0;
21294 }
21295
21296 static int
21297 get_msg_id (vat_main_t * vam)
21298 {
21299   u8 *name_and_crc;
21300   u32 message_index;
21301
21302   if (unformat (vam->input, "%s", &name_and_crc))
21303     {
21304       message_index = vl_api_get_msg_index (name_and_crc);
21305       if (message_index == ~0)
21306         {
21307           print (vam->ofp, " '%s' not found", name_and_crc);
21308           return 0;
21309         }
21310       print (vam->ofp, " '%s' has message index %d",
21311              name_and_crc, message_index);
21312       return 0;
21313     }
21314   errmsg ("name_and_crc required...");
21315   return 0;
21316 }
21317
21318 static int
21319 search_node_table (vat_main_t * vam)
21320 {
21321   unformat_input_t *line_input = vam->input;
21322   u8 *node_to_find;
21323   int j;
21324   vlib_node_t *node, *next_node;
21325   uword *p;
21326
21327   if (vam->graph_node_index_by_name == 0)
21328     {
21329       print (vam->ofp, "Node table empty, issue get_node_graph...");
21330       return 0;
21331     }
21332
21333   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21334     {
21335       if (unformat (line_input, "%s", &node_to_find))
21336         {
21337           vec_add1 (node_to_find, 0);
21338           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21339           if (p == 0)
21340             {
21341               print (vam->ofp, "%s not found...", node_to_find);
21342               goto out;
21343             }
21344           node = vam->graph_nodes[p[0]];
21345           print (vam->ofp, "[%d] %s", p[0], node->name);
21346           for (j = 0; j < vec_len (node->next_nodes); j++)
21347             {
21348               if (node->next_nodes[j] != ~0)
21349                 {
21350                   next_node = vam->graph_nodes[node->next_nodes[j]];
21351                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21352                 }
21353             }
21354         }
21355
21356       else
21357         {
21358           clib_warning ("parse error '%U'", format_unformat_error,
21359                         line_input);
21360           return -99;
21361         }
21362
21363     out:
21364       vec_free (node_to_find);
21365
21366     }
21367
21368   return 0;
21369 }
21370
21371
21372 static int
21373 script (vat_main_t * vam)
21374 {
21375 #if (VPP_API_TEST_BUILTIN==0)
21376   u8 *s = 0;
21377   char *save_current_file;
21378   unformat_input_t save_input;
21379   jmp_buf save_jump_buf;
21380   u32 save_line_number;
21381
21382   FILE *new_fp, *save_ifp;
21383
21384   if (unformat (vam->input, "%s", &s))
21385     {
21386       new_fp = fopen ((char *) s, "r");
21387       if (new_fp == 0)
21388         {
21389           errmsg ("Couldn't open script file %s", s);
21390           vec_free (s);
21391           return -99;
21392         }
21393     }
21394   else
21395     {
21396       errmsg ("Missing script name");
21397       return -99;
21398     }
21399
21400   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21401   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21402   save_ifp = vam->ifp;
21403   save_line_number = vam->input_line_number;
21404   save_current_file = (char *) vam->current_file;
21405
21406   vam->input_line_number = 0;
21407   vam->ifp = new_fp;
21408   vam->current_file = s;
21409   do_one_file (vam);
21410
21411   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21412   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21413   vam->ifp = save_ifp;
21414   vam->input_line_number = save_line_number;
21415   vam->current_file = (u8 *) save_current_file;
21416   vec_free (s);
21417
21418   return 0;
21419 #else
21420   clib_warning ("use the exec command...");
21421   return -99;
21422 #endif
21423 }
21424
21425 static int
21426 echo (vat_main_t * vam)
21427 {
21428   print (vam->ofp, "%v", vam->input->buffer);
21429   return 0;
21430 }
21431
21432 /* List of API message constructors, CLI names map to api_xxx */
21433 #define foreach_vpe_api_msg                                             \
21434 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21435 _(sw_interface_dump,"")                                                 \
21436 _(sw_interface_set_flags,                                               \
21437   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21438 _(sw_interface_add_del_address,                                         \
21439   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21440 _(sw_interface_set_table,                                               \
21441   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21442 _(sw_interface_set_mpls_enable,                                         \
21443   "<intfc> | sw_if_index [disable | dis]")                              \
21444 _(sw_interface_set_vpath,                                               \
21445   "<intfc> | sw_if_index <id> enable | disable")                        \
21446 _(sw_interface_set_vxlan_bypass,                                        \
21447   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21448 _(sw_interface_set_geneve_bypass,                                       \
21449   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21450 _(sw_interface_set_l2_xconnect,                                         \
21451   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21452   "enable | disable")                                                   \
21453 _(sw_interface_set_l2_bridge,                                           \
21454   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21455   "[shg <split-horizon-group>] [bvi]\n"                                 \
21456   "enable | disable")                                                   \
21457 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21458 _(bridge_domain_add_del,                                                \
21459   "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") \
21460 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21461 _(l2fib_add_del,                                                        \
21462   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21463 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21464 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21465 _(l2_flags,                                                             \
21466   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21467 _(bridge_flags,                                                         \
21468   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21469 _(tap_connect,                                                          \
21470   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21471 _(tap_modify,                                                           \
21472   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21473 _(tap_delete,                                                           \
21474   "<vpp-if-name> | sw_if_index <id>")                                   \
21475 _(sw_interface_tap_dump, "")                                            \
21476 _(ip_table_add_del,                                                     \
21477   "table-id <n> [ipv6]\n")                                              \
21478 _(ip_add_del_route,                                                     \
21479   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21480   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21481   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21482   "[multipath] [count <n>]")                                            \
21483 _(ip_mroute_add_del,                                                    \
21484   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21485   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21486 _(mpls_table_add_del,                                                   \
21487   "table-id <n>\n")                                                     \
21488 _(mpls_route_add_del,                                                   \
21489   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21490   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21491   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21492   "[multipath] [count <n>]")                                            \
21493 _(mpls_ip_bind_unbind,                                                  \
21494   "<label> <addr/len>")                                                 \
21495 _(mpls_tunnel_add_del,                                                  \
21496   " via <addr> [table-id <n>]\n"                                        \
21497   "sw_if_index <id>] [l2]  [del]")                                      \
21498 _(proxy_arp_add_del,                                                    \
21499   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21500 _(proxy_arp_intfc_enable_disable,                                       \
21501   "<intfc> | sw_if_index <id> enable | disable")                        \
21502 _(sw_interface_set_unnumbered,                                          \
21503   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21504 _(ip_neighbor_add_del,                                                  \
21505   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21506   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21507 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21508 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21509 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21510   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21511   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21512   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21513 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21514 _(reset_fib, "vrf <n> [ipv6]")                                          \
21515 _(dhcp_proxy_config,                                                    \
21516   "svr <v46-address> src <v46-address>\n"                               \
21517    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21518 _(dhcp_proxy_set_vss,                                                   \
21519   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21520 _(dhcp_proxy_dump, "ip6")                                               \
21521 _(dhcp_client_config,                                                   \
21522   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21523 _(set_ip_flow_hash,                                                     \
21524   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21525 _(sw_interface_ip6_enable_disable,                                      \
21526   "<intfc> | sw_if_index <id> enable | disable")                        \
21527 _(sw_interface_ip6_set_link_local_address,                              \
21528   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21529 _(ip6nd_proxy_add_del,                                                  \
21530   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21531 _(ip6nd_proxy_dump, "")                                                 \
21532 _(sw_interface_ip6nd_ra_prefix,                                         \
21533   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21534   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21535   "[nolink] [isno]")                                                    \
21536 _(sw_interface_ip6nd_ra_config,                                         \
21537   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21538   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21539   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21540 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21541 _(l2_patch_add_del,                                                     \
21542   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21543   "enable | disable")                                                   \
21544 _(sr_localsid_add_del,                                                  \
21545   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21546   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21547 _(classify_add_del_table,                                               \
21548   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21549   " [del] [del-chain] mask <mask-value>\n"                              \
21550   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21551   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21552 _(classify_add_del_session,                                             \
21553   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21554   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21555   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21556   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21557 _(classify_set_interface_ip_table,                                      \
21558   "<intfc> | sw_if_index <nn> table <nn>")                              \
21559 _(classify_set_interface_l2_tables,                                     \
21560   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21561   "  [other-table <nn>]")                                               \
21562 _(get_node_index, "node <node-name")                                    \
21563 _(add_node_next, "node <node-name> next <next-node-name>")              \
21564 _(l2tpv3_create_tunnel,                                                 \
21565   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21566   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21567   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21568 _(l2tpv3_set_tunnel_cookies,                                            \
21569   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21570   "[new_remote_cookie <nn>]\n")                                         \
21571 _(l2tpv3_interface_enable_disable,                                      \
21572   "<intfc> | sw_if_index <nn> enable | disable")                        \
21573 _(l2tpv3_set_lookup_key,                                                \
21574   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21575 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21576 _(vxlan_add_del_tunnel,                                                 \
21577   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21578   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21579   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21580 _(geneve_add_del_tunnel,                                                \
21581   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21582   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21583   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21584 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21585 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21586 _(gre_add_del_tunnel,                                                   \
21587   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21588 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21589 _(l2_fib_clear_table, "")                                               \
21590 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21591 _(l2_interface_vlan_tag_rewrite,                                        \
21592   "<intfc> | sw_if_index <nn> \n"                                       \
21593   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21594   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21595 _(create_vhost_user_if,                                                 \
21596         "socket <filename> [server] [renumber <dev_instance>] "         \
21597         "[mac <mac_address>]")                                          \
21598 _(modify_vhost_user_if,                                                 \
21599         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21600         "[server] [renumber <dev_instance>]")                           \
21601 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21602 _(sw_interface_vhost_user_dump, "")                                     \
21603 _(show_version, "")                                                     \
21604 _(vxlan_gpe_add_del_tunnel,                                             \
21605   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21606   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21607   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21608   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21609 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21610 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21611 _(interface_name_renumber,                                              \
21612   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21613 _(input_acl_set_interface,                                              \
21614   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21615   "  [l2-table <nn>] [del]")                                            \
21616 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21617 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21618 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21619 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21620 _(ip_dump, "ipv4 | ipv6")                                               \
21621 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21622 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21623   "  spid_id <n> ")                                                     \
21624 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21625   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21626   "  integ_alg <alg> integ_key <hex>")                                  \
21627 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21628   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21629   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21630   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21631 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21632 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21633   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21634   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21635   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21636 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21637 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21638   "  <alg> <hex>\n")                                                    \
21639 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21640 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21641   "(auth_data 0x<data> | auth_data <data>)")                            \
21642 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21643   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21644 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21645   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21646   "(local|remote)")                                                     \
21647 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21648 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21649 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21650 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21651 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21652 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21653 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21654 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21655 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21656 _(delete_loopback,"sw_if_index <nn>")                                   \
21657 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21658 _(map_add_domain,                                                       \
21659   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21660   "ip6-src <ip6addr> "                                                  \
21661   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21662 _(map_del_domain, "index <n>")                                          \
21663 _(map_add_del_rule,                                                     \
21664   "index <n> psid <n> dst <ip6addr> [del]")                             \
21665 _(map_domain_dump, "")                                                  \
21666 _(map_rule_dump, "index <map-domain>")                                  \
21667 _(want_interface_events,  "enable|disable")                             \
21668 _(want_stats,"enable|disable")                                          \
21669 _(get_first_msg_id, "client <name>")                                    \
21670 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21671 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21672   "fib-id <nn> [ip4][ip6][default]")                                    \
21673 _(get_node_graph, " ")                                                  \
21674 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21675 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21676 _(ioam_disable, "")                                                     \
21677 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21678                             " sw_if_index <sw_if_index> p <priority> "  \
21679                             "w <weight>] [del]")                        \
21680 _(one_add_del_locator, "locator-set <locator_name> "                    \
21681                         "iface <intf> | sw_if_index <sw_if_index> "     \
21682                         "p <priority> w <weight> [del]")                \
21683 _(one_add_del_local_eid,"vni <vni> eid "                                \
21684                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21685                          "locator-set <locator_name> [del]"             \
21686                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21687 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21688 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21689 _(one_enable_disable, "enable|disable")                                 \
21690 _(one_map_register_enable_disable, "enable|disable")                    \
21691 _(one_map_register_fallback_threshold, "<value>")                       \
21692 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21693 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21694                                "[seid <seid>] "                         \
21695                                "rloc <locator> p <prio> "               \
21696                                "w <weight> [rloc <loc> ... ] "          \
21697                                "action <action> [del-all]")             \
21698 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21699                           "<local-eid>")                                \
21700 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21701 _(one_use_petr, "ip-address> | disable")                                \
21702 _(one_map_request_mode, "src-dst|dst-only")                             \
21703 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21704 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21705 _(one_locator_set_dump, "[local | remote]")                             \
21706 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21707 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21708                        "[local] | [remote]")                            \
21709 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21710 _(one_ndp_bd_get, "")                                                   \
21711 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21712 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21713 _(one_l2_arp_bd_get, "")                                                \
21714 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21715 _(one_stats_enable_disable, "enable|disalbe")                           \
21716 _(show_one_stats_enable_disable, "")                                    \
21717 _(one_eid_table_vni_dump, "")                                           \
21718 _(one_eid_table_map_dump, "l2|l3")                                      \
21719 _(one_map_resolver_dump, "")                                            \
21720 _(one_map_server_dump, "")                                              \
21721 _(one_adjacencies_get, "vni <vni>")                                     \
21722 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21723 _(show_one_rloc_probe_state, "")                                        \
21724 _(show_one_map_register_state, "")                                      \
21725 _(show_one_status, "")                                                  \
21726 _(one_stats_dump, "")                                                   \
21727 _(one_stats_flush, "")                                                  \
21728 _(one_get_map_request_itr_rlocs, "")                                    \
21729 _(one_map_register_set_ttl, "<ttl>")                                    \
21730 _(one_set_transport_protocol, "udp|api")                                \
21731 _(one_get_transport_protocol, "")                                       \
21732 _(show_one_nsh_mapping, "")                                             \
21733 _(show_one_pitr, "")                                                    \
21734 _(show_one_use_petr, "")                                                \
21735 _(show_one_map_request_mode, "")                                        \
21736 _(show_one_map_register_ttl, "")                                        \
21737 _(show_one_map_register_fallback_threshold, "")                         \
21738 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21739                             " sw_if_index <sw_if_index> p <priority> "  \
21740                             "w <weight>] [del]")                        \
21741 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21742                         "iface <intf> | sw_if_index <sw_if_index> "     \
21743                         "p <priority> w <weight> [del]")                \
21744 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21745                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21746                          "locator-set <locator_name> [del]"             \
21747                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21748 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21749 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21750 _(lisp_enable_disable, "enable|disable")                                \
21751 _(lisp_map_register_enable_disable, "enable|disable")                   \
21752 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21753 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21754                                "[seid <seid>] "                         \
21755                                "rloc <locator> p <prio> "               \
21756                                "w <weight> [rloc <loc> ... ] "          \
21757                                "action <action> [del-all]")             \
21758 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21759                           "<local-eid>")                                \
21760 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21761 _(lisp_use_petr, "<ip-address> | disable")                              \
21762 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21763 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21764 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21765 _(lisp_locator_set_dump, "[local | remote]")                            \
21766 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21767 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21768                        "[local] | [remote]")                            \
21769 _(lisp_eid_table_vni_dump, "")                                          \
21770 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21771 _(lisp_map_resolver_dump, "")                                           \
21772 _(lisp_map_server_dump, "")                                             \
21773 _(lisp_adjacencies_get, "vni <vni>")                                    \
21774 _(gpe_fwd_entry_vnis_get, "")                                           \
21775 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21776 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21777                                 "[table <table-id>]")                   \
21778 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21779 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21780 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21781 _(gpe_get_encap_mode, "")                                               \
21782 _(lisp_gpe_add_del_iface, "up|down")                                    \
21783 _(lisp_gpe_enable_disable, "enable|disable")                            \
21784 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21785   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21786 _(show_lisp_rloc_probe_state, "")                                       \
21787 _(show_lisp_map_register_state, "")                                     \
21788 _(show_lisp_status, "")                                                 \
21789 _(lisp_get_map_request_itr_rlocs, "")                                   \
21790 _(show_lisp_pitr, "")                                                   \
21791 _(show_lisp_use_petr, "")                                               \
21792 _(show_lisp_map_request_mode, "")                                       \
21793 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21794 _(af_packet_delete, "name <host interface name>")                       \
21795 _(policer_add_del, "name <policer name> <params> [del]")                \
21796 _(policer_dump, "[name <policer name>]")                                \
21797 _(policer_classify_set_interface,                                       \
21798   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21799   "  [l2-table <nn>] [del]")                                            \
21800 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21801 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21802     "[master|slave]")                                                   \
21803 _(netmap_delete, "name <interface name>")                               \
21804 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21805 _(mpls_fib_dump, "")                                                    \
21806 _(classify_table_ids, "")                                               \
21807 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21808 _(classify_table_info, "table_id <nn>")                                 \
21809 _(classify_session_dump, "table_id <nn>")                               \
21810 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21811     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21812     "[template_interval <nn>] [udp_checksum]")                          \
21813 _(ipfix_exporter_dump, "")                                              \
21814 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21815 _(ipfix_classify_stream_dump, "")                                       \
21816 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21817 _(ipfix_classify_table_dump, "")                                        \
21818 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21819 _(sw_interface_span_dump, "[l2]")                                           \
21820 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21821 _(pg_create_interface, "if_id <nn>")                                    \
21822 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21823 _(pg_enable_disable, "[stream <id>] disable")                           \
21824 _(ip_source_and_port_range_check_add_del,                               \
21825   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21826 _(ip_source_and_port_range_check_interface_add_del,                     \
21827   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21828   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21829 _(ipsec_gre_add_del_tunnel,                                             \
21830   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21831 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21832 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21833 _(l2_interface_pbb_tag_rewrite,                                         \
21834   "<intfc> | sw_if_index <nn> \n"                                       \
21835   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21836   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21837 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21838 _(flow_classify_set_interface,                                          \
21839   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21840 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21841 _(ip_fib_dump, "")                                                      \
21842 _(ip_mfib_dump, "")                                                     \
21843 _(ip6_fib_dump, "")                                                     \
21844 _(ip6_mfib_dump, "")                                                    \
21845 _(feature_enable_disable, "arc_name <arc_name> "                        \
21846   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21847 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21848 "[disable]")                                                            \
21849 _(l2_xconnect_dump, "")                                                 \
21850 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21851 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21852 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21853 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21854 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21855 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21856 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21857   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21858 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21859 _(memfd_segment_create,"size <nnn>")                                    \
21860 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21861 _(dns_enable_disable, "[enable][disable]")                              \
21862 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21863 _(dns_resolve_name, "<hostname>")
21864
21865 /* List of command functions, CLI names map directly to functions */
21866 #define foreach_cli_function                                    \
21867 _(comment, "usage: comment <ignore-rest-of-line>")              \
21868 _(dump_interface_table, "usage: dump_interface_table")          \
21869 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21870 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21871 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21872 _(dump_stats_table, "usage: dump_stats_table")                  \
21873 _(dump_macro_table, "usage: dump_macro_table ")                 \
21874 _(dump_node_table, "usage: dump_node_table")                    \
21875 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21876 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21877 _(echo, "usage: echo <message>")                                \
21878 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21879 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21880 _(help, "usage: help")                                          \
21881 _(q, "usage: quit")                                             \
21882 _(quit, "usage: quit")                                          \
21883 _(search_node_table, "usage: search_node_table <name>...")      \
21884 _(set, "usage: set <variable-name> <value>")                    \
21885 _(script, "usage: script <file-name>")                          \
21886 _(unset, "usage: unset <variable-name>")
21887 #define _(N,n)                                  \
21888     static void vl_api_##n##_t_handler_uni      \
21889     (vl_api_##n##_t * mp)                       \
21890     {                                           \
21891         vat_main_t * vam = &vat_main;           \
21892         if (vam->json_output) {                 \
21893             vl_api_##n##_t_handler_json(mp);    \
21894         } else {                                \
21895             vl_api_##n##_t_handler(mp);         \
21896         }                                       \
21897     }
21898 foreach_vpe_api_reply_msg;
21899 #if VPP_API_TEST_BUILTIN == 0
21900 foreach_standalone_reply_msg;
21901 #endif
21902 #undef _
21903
21904 void
21905 vat_api_hookup (vat_main_t * vam)
21906 {
21907 #define _(N,n)                                                  \
21908     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21909                            vl_api_##n##_t_handler_uni,          \
21910                            vl_noop_handler,                     \
21911                            vl_api_##n##_t_endian,               \
21912                            vl_api_##n##_t_print,                \
21913                            sizeof(vl_api_##n##_t), 1);
21914   foreach_vpe_api_reply_msg;
21915 #if VPP_API_TEST_BUILTIN == 0
21916   foreach_standalone_reply_msg;
21917 #endif
21918 #undef _
21919
21920 #if (VPP_API_TEST_BUILTIN==0)
21921   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21922
21923   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21924
21925   vam->function_by_name = hash_create_string (0, sizeof (uword));
21926
21927   vam->help_by_name = hash_create_string (0, sizeof (uword));
21928 #endif
21929
21930   /* API messages we can send */
21931 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21932   foreach_vpe_api_msg;
21933 #undef _
21934
21935   /* Help strings */
21936 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21937   foreach_vpe_api_msg;
21938 #undef _
21939
21940   /* CLI functions */
21941 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21942   foreach_cli_function;
21943 #undef _
21944
21945   /* Help strings */
21946 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21947   foreach_cli_function;
21948 #undef _
21949 }
21950
21951 #if VPP_API_TEST_BUILTIN
21952 static clib_error_t *
21953 vat_api_hookup_shim (vlib_main_t * vm)
21954 {
21955   vat_api_hookup (&vat_main);
21956   return 0;
21957 }
21958
21959 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21960 #endif
21961
21962 /*
21963  * fd.io coding-style-patch-verification: ON
21964  *
21965  * Local Variables:
21966  * eval: (c-set-style "gnu")
21967  * End:
21968  */